7

我想要做什么

在 Swing 中,我尝试使用BoxLayout或等效的线性容器,但容器中的项目垂直拉伸。在我的应用程序中,我不希望它们垂直拉伸。

我知道我可以在组件上设置一个 preferredSize 或 maximumSize,但是下面的代码只是一个复制器,我不能硬编码或最大化组件的大小,这些组件实际上更复杂和动态。而且我不能将 aBorderLayout与该BorderLayout.TOP位置一起使用,因为如果我这样做,将不会显示任何滚动条。我可能需要滚动窗格。


我试过的

因此,我尝试按照Using Invisible Components as Filler中的说明使用fillersin a ,但它不起作用。尽管在 Oracle 文档中,它似乎正是我所需要的。这是我的尝试:BoxLayout

    import javax.swing.Box;
    import javax.swing.BoxLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;


    public class TestBoxLayout implements Runnable {

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new TestBoxLayout());
        }

        @Override
        public void run() {
            JFrame f = new JFrame("test box layout");

            JPanel b = new JPanel();
            b.setLayout(new BoxLayout(b, BoxLayout.PAGE_AXIS));

            b.add(new JTextField("field 1"));
            b.add(new JTextField("field 2"));
            b.add(new JTextField("field 3"));
            b.add(Box.createVerticalGlue());

            f.setContentPane(b);
            f.setSize(500, 200);
            f.setVisible(true);
        }

    }

这是我得到的结果:

填充物不起作用


第二次尝试

我尝试使用Box类而不是JPanelwith BoxLayout,但视觉结果完全相同。这是我的第二次尝试:

    import javax.swing.Box;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;


    public class TestBox implements Runnable {

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new TestBox());
        }

        @Override
        public void run() {
            JFrame f = new JFrame("test box");

            Box b = Box.createVerticalBox();

            b.add(new JTextField("field 1"));
            b.add(new JTextField("field 2"));
            b.add(new JTextField("field 3"));
            b.add(Box.createVerticalGlue());

            f.setContentPane(b);
            f.setSize(500, 200);
            f.setVisible(true);
        }

    }

我想做什么

有谁知道我如何修复这些填充物并使它们起作用?对给定代码的修复会很棒。

这是我用颜料画的一幅画,它显示了我想要的结果: 预期结果

4

3 回答 3

2

BoxLayout 非常适合您尝试做的事情。作为最后一个组件的胶水插件很好。为什么不简单地在 JTextFields 上使用 setMaximumSize 方法?我不确定单独的 JTextFields 能否满足您的需求。如果使用 setMaximumSize 不起作用,请将每个 JTextField 放入 JPanel 中,然后在每个 JPanel 上使用 setMaximumSize。

于 2011-06-29T13:15:13.923 回答
1

OP 询问他如何仅使用 s制作BoxLayout尊重垂直胶水。JTextField文本字段的最大高度可以从getPreferredSize().

但是,在我的情况下,我也需要JTextArea,情况变得更加奇怪:JTextArea尽管我限制了JTextArea.

下面的代码修复了 s 的 OP 问题JTextField,但问题JTextArea仍然存在(当您取消注释注释部分时,您会看到一些“有趣”的行为)。

import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TestBox implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TestBox());
    }

    @Override
    public void run() {
        JFrame f = new JFrame("test box");

        Box b = Box.createVerticalBox();

        JTextField field1 = new JTextField();
        JTextField field2 = new JTextField();
        field1.setMaximumSize(new Dimension(Integer.MAX_VALUE, field1.getPreferredSize().height));
        field2.setMaximumSize(new Dimension(Integer.MAX_VALUE, field2.getPreferredSize().height));
        b.add(field1);
        b.add(field2);

//        JTextArea area = new JTextArea();
//        area.setRows(4);
//        area.setMaximumSize(new Dimension(Integer.MAX_VALUE, area.getPreferredSize().height));
//        b.add(new JScrollPane(area));

        b.add(Box.createVerticalGlue());

        f.setContentPane(b);
        f.setSize(500, 200);
        f.setVisible(true);
    }
}
于 2012-08-06T14:40:46.117 回答
0

许多帖子谴责 Box 在胶水大小和内容对齐方面的缺点。这些问题源于 BoxLayout 使用 SizeRequirements 方法 calculateTiledPositions 和 calculateAlignedPositions。这些方法非常简洁,但过于简单,以至于结果通常无法匹配预期的行为。

原始问题的解决方法是为胶水的首选尺寸设置一个较大的值:

    Box.Filler glue = (Box.Filler) Box.createVerticalGlue();
    glue.changeShape(glue.getMinimumSize(), 
           new Dimension(0, Short.MAX_VALUE),   // prefer it big
           glue.getMaximumSize());
    b.add(glue);

这适用于三个 JTextField,但在添加滚动的 JTextArea 时无效。更通用的解决方案是将 Box 的 LayoutManager 设置为重写 layoutContainer() 的 BoxLayout 子类。用更适合您需要的代码替换对上述方法的调用。

于 2014-09-04T01:16:06.870 回答