23

我试图让我的布局JDialog适合我移植到 Java 的程序所具有的特定外观,我之前使用过几个 LayoutManagers 并取得了巨大成功,但由于某种原因我似乎无法得到这个工作。我的目标是让右侧(东)侧以JDialog自上而下的顺序包含“查找下一个”和“取消”按钮,然后是下方的任何额外空间,以便这两个按钮始终位于顶部JDialog,然而出于某种原因BoxLayout,它一直忽略任何改变(这是我迷路的地方)宽度的尝试 a JButton。代码如下。

JButton findNext = new JButton("Find Next");
JButton cancel = new JButton("Cancel");
cancel.setPreferredSize(new Dimension((int)findNext.getPreferredSize().getWidth(),  
    (int)cancel.getPreferredSize().getHeight()));

JPanel example = new JPanel();  
example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS));  
example.add(findNext);
example.add(cancel);  
example.add(Box.createGlue());  

无论我尝试什么,cancel始终保持正常大小。我已经尝试过使用setMinimumSize()与没有运气setMaximumSize()相同的参数。setPreferredSize我什至尝试过cancel.setPreferredSize(new Dimension(500, 500));,按钮高度是唯一调整的,它仍然保留了给定的默认宽度。

为了澄清任何问题,下面是它的样子(现在我已经完成了),您会看到“查找下一个”和“取消”按钮的大小不同。

示例图像

4

6 回答 6

53

我知道这是一个老问题,但我真的没有看到一个好的解释。因此,为了偶然发现这一点的搜索者,我将添加我的两分钱。

在 Swing 中,有三种与调整组件大小相关的方法:setPreferredSize()、setMinimumSize() 和 setMaximumSize()。然而,重要的一点是,它是否支持这些方法中的任何一个都取决于所使用的特定布局管理器。

对于 BoxLayout(原始海报使用的布局):

  • setMinimumSize() -BoxLayout尊重这个
  • setMaximumSize() -BoxLayout尊重这个
  • setPreferredSize() -- 如果使用 X_AXIS,则使用宽度,如果使用 Y_AXIS,则使用高度

OP 使用的是 Y_AXIS BoxLayout,这就是为什么只有他的身高被改变了。

更新:我为所有布局管理器整理了一个包含相同信息的页面。希望它可以帮助一些搜索者:http ://thebadprogrammer.com/swing-layout-manager-sizing/

于 2011-05-12T16:40:20.723 回答
9

您可能不想要Box.createGlue(),它“根据需要增长以吸收其容器中的任何额外空间”。而是在按钮之间使用,如下所示,在此模拟中。Box.createVerticalStrut() ControlPanel

example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS));
example.add(findNext);
Box.createVerticalStrut(10);
example.add(cancel);

附录:

添加setMaximumSize()使它工作。

这是在垂直方向上具有相同最大宽度的组件的预期行为BoxLayout,如Box Layout Features中所述。容器的首选宽度变为(同样宽的)子容器的宽度,并且 X 对齐变得无关紧要。

example.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JButton findNext = new JButton("Find Next");
JButton cancel = new JButton("Cancel");
Dimension d = findNext.getMaximumSize();
cancel.setMaximumSize(new Dimension(d));
example.add(findNext);
example.add(cancel);
于 2010-09-12T00:18:02.810 回答
3

如对该问题的评论中所述,您可以通过切换到setMaximumSize(). 但是,正如您所指出的,setPreferredSize()它不起作用。那么,这是怎么回事?

对于 Swing 的许多东西,用于确定实际组件大小的属性在使用时BoxLayout有些随机(在我看来)。当确定如何渲染组件时,Swing 调用layoutComponent()布局管理器,它会计算出所有内容的位置。

BoxLayout的实现layoutComponent()涉及到一个方法的调用,该方法根据它们的方法SizeRequirements为添加到 的每个组件的宽度和高度创建对象。JPanelgetMinimum/Preferred/MaximumSize()

稍后,它要求SizeRequirements.calculateAlignedPositions()为每个组件确定正确的宽度值,因为您的方向是BoxLayout.Y_AXIS(使用不同的方法计算高度)。摘取源码,该方法的相关实现如下:

for (int i = 0; i < children.length; i++) {
    SizeRequirements req = children[i];
    //...
    int maxAscent = (int)(req.maximum * alignment);
    int maxDescent = req.maximum - maxAscent;
    //...
    int descent = Math.min(totalDescent, maxDescent);
    //...
    spans[i] = (int)Math.min((long) ascent + (long)descent, Integer.MAX_VALUE);
}

请注意,这totalDescent是可用宽度,因此descent始终设置为maxDescent,它基于SizeRequirements.maximum,取自JButton.getMaximumSize()。的值spans[i]随后在调用中JButton.setBounds()用作宽度。正如您将注意到的,getPreferredSize()这里从未涉及,这就是为什么在这种情况下设置它没有影响。

于 2010-09-12T03:40:26.980 回答
0
button.setMaximumSize(getMaximumSize());
于 2013-03-09T10:41:13.123 回答
0

通常,如果要确保 Swing 中组件的大小,您需要调用setMinimumSize(), setMaximumSize(), 和SetPrefferedSize()具有相同的值。

于 2010-09-12T04:57:48.627 回答
0

如果您将按钮放在 GridLayout 面板中,它们将具有相同的宽度。

于 2017-05-04T21:04:38.003 回答