BoxLayout会拉伸组件以适应父面板。

23

嗨,我正在使用BoxLayoutJPanel在其上方堆叠(BoxLayout.Y_AXIS),例如,如果我的父JPanel高度为500像素,并且我添加两个子面板,每个高度为100像素,则BoxLayout会拉伸它们,使其共占用500px的空间。有人知道如何禁用此功能吗?


你是如何指定子面板的大小的? - Ascalonian
1
使用 panel.setPrefferedSize 和 panel.setMinimumSize 两者都使用相同的 Dimension。 - Aly
5个回答

24

BoxLayout是少数几个布局管理器之一,它尊重组件的最小和最大尺寸。因此,如果您想要防止面板拉伸,可以使用以下代码:

panel.setMaximumSize( panel.getPreferredSize() );

这可能是一段时间以前的事了,但是是否使用了重写的getPreferredSize()方法? - MikeM
@MikeM,不,因为面板依赖于布局管理器返回首选大小。实际上,更好的解决方案是扩展JPanel并覆盖getMaximumSize()方法,以简单地从getPreferredSize()方法返回值。这样,最大尺寸将在首选尺寸动态更改的情况下动态计算。 - camickr

13

使用GridBagLayout代替。这样你可以更好地控制用户界面。

但如果你仍想使用BoxLayout,并且不希望它们被拉伸,那么你可以考虑使用不可见组件填充器,如刚性区域、粘合剂和填充器。


4
如果您要对我进行负评,请提供原因。 - Ascalonian
请务必查看链接中发布的“水平粘合”部分。非常有帮助。 - FuriousFolder

4
这似乎完美地运行了...使用BoxLayout,就像您想要的那样。

测试

    this.setLayout(new FlowLayout()); // this being the JFrame

    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.setPreferredSize(new Dimension(500, 500));
    panel.setBackground(Color.orange);
    this.add(panel); // add the parent to the JFrame

    JPanel pnlChild1 = new JPanel();
    pnlChild1.setBackground(Color.cyan);
    pnlChild1.setMaximumSize(new Dimension(200, 100));

    JPanel pnlChild2 = new JPanel();
    pnlChild2.setBackground(Color.magenta);
    pnlChild2.setMaximumSize(new Dimension(200, 100));

    panel.add(pnlChild1);
    panel.add(pnlChild2);

4
技巧在于,就像之前的回答所提到的那样,使用盒式布局中的粘合剂、填充物和刚性区域。不过,与那位回答者不同的是,我建议使用BoxLayout - 你可以用Box比Grid Bag更容易地完成大多数简单的UI设计;而且在典型的对话框中,额外的功能并不能为你带来太多帮助。
在旧的成语中,这些东西被称为Box.createHorizontalStrut(int x)和Box.createHorizontalGlue()等。其思想是在第一个和第二个组件之间放置一个支撑柱,然后在第二个组件之后添加一个粘合剂。("支撑柱"现在被称为"刚性区域")。

对于一般的堆叠布局,我同意GridBagLayout可能有些过度了。只是建议如果他继续前进可以考虑使用它。 - Ascalonian
我尝试在两个子面板之间放置一个刚性区域,并在第二个面板后放置垂直粘合剂,但面板仍然被拉伸:s - Aly
没有所谓的过度设计 :) - willcodejavaforfood
尝试为底部的两个面板添加一个面板容器,然后将它们自己粘在一个框里...我不清楚您要寻找的排列方式,但您可以随时想出一些子面板、支撑和粘合的组合,使事物不会被拉伸。 - M1EK

3
你的面板正在被拉伸,因为BoxLayout不能限制每个面板的首选大小。你需要找到能够尊重组件首选大小的布局管理器,例如BorderLayout的NORTH和SOUTH位置。
请尝试以下步骤:
1. 创建一个具有BorderLayout的JPanel,并将您的子组件添加为该JPanel的NORTH。 2. 为另一个子组件创建第二个JPanel,在BorderLayout的NORTH位置上添加它。 3. 将这两个JPanel添加到您的BoxLayout中。
代码:
JPanel panel1 = new JPanel(new BorderLayout());
panel1.add(component1, BorderLayout.NORTH);
JPanel panel2 = new JPanel(new BorderLayout());
panel2.add(component2, BorderLayout.NORTH);

JPanel boxPanel = new JPanel();
BoxLayout boxLayout = new BoxLayout(boxPanel, BoxLayout.Y_AXIS);
boxPanel.setLayout(boxLayout);
boxPanel.add(panel1);
boxPanel.add(panel2);

1
我喜欢这个解决方案,因为它避免了与 gridbag 打交道和修改组件本身,这两点都是很大的优点。 - William Jarvis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接