Java 为什么 BoxLayout 不允许我更改 JButton 的宽度但让我更改高度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3692987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why will BoxLayout not allow me to change the width of a JButton but let me change the height?
提问by Brandon Buck
I'm trying to get the Layout of a JDialog
of mine to fit a particular look that a program in which I'm porting to Java has, I've used several LayoutManagers before with great success yet for some reason I cannot seem to get this working at all. My goal is to have the Right (East) side of the JDialog
contain a "Find Next" and "Cancel" button in a top-down order and then any extra space below so that the two buttons are always at the top of the JDialog
, yet for some reason BoxLayout
is continously ignoring any attempts at changing (this is where I'm lost) the width of a JButton
. Code follows.
我正在尝试使我的布局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());
No matter what I try, cancel
always retains it's normal size. I've tried setMinimumSize()
and setMaximumSize()
with the same parameters as setPreferredSize
with no luck. I've even tried cancel.setPreferredSize(new Dimension(500, 500));
and the buttons height was the only thing adjusted, it STILL retained the default width it was given.
无论我尝试什么,cancel
始终保持其正常大小。我已经尝试过setMinimumSize()
并且setMaximumSize()
使用setPreferredSize
与没有运气相同的参数。我什至尝试过cancel.setPreferredSize(new Dimension(500, 500));
,按钮高度是唯一调整的东西,它仍然保留给定的默认宽度。
To clear up any questions, here is what it looks like (now that I've finished it) and you'll see that the "Find Next" and "Cancel" buttons are not the same size.
为了解决任何问题,这是它的外观(现在我已经完成了),您会看到“查找下一个”和“取消”按钮的大小不同。
采纳答案by Michael
I know this is an old question but I don't really see a good explanation. So for the sake of searchers that stumble upon this I will add my two cents.
我知道这是一个老问题,但我真的没有看到好的解释。因此,为了偶然发现这一点的搜索者,我将添加我的两分钱。
There are three methods associated with sizing components in Swing: setPreferredSize(), setMinimumSize(), and setMaximumSize(). However, the important point is that it is up to the particular layout manager being used as to whether or not it honors any of these methods.
Swing 中有三种与调整组件大小相关的方法:setPreferredSize()、setMinimumSize() 和 setMaximumSize()。然而,重要的一点是,它是否支持这些方法中的任何一种取决于所使用的特定布局管理器。
For BoxLayout (the layout the original poster is using):
对于 BoxLayout(原始海报使用的布局):
- setMinimumSize() --
BoxLayout
honors this - setMaximumSize() --
BoxLayout
honors this - setPreferredSize() -- if X_AXIS is being used width is honored, if Y_AXIS is being used height is honored
- setMinimumSize() --
BoxLayout
尊重这一点 - setMaximumSize() --
BoxLayout
尊重这一点 - setPreferredSize() -- 如果使用 X_AXIS,则使用宽度,如果使用 Y_AXIS,则使用高度
The OP is using a Y_AXIS BoxLayout which is why only his height was being changed.
OP 使用的是 Y_AXIS BoxLayout,这就是为什么只改变了他的高度。
Update:I put together a page with this same information for all of the layout managers. Hopefully it can help some searchers out: http://thebadprogrammer.com/swing-layout-manager-sizing/
更新:我为所有布局管理器整理了一个包含相同信息的页面。希望它可以帮助一些搜索者:http: //thebadprogrammer.com/swing-layout-manager-sizing/
回答by trashgod
You may not want Box.createGlue()
, which "grows as necessaryto absorb any extra space in its container." Instead, use Box.createVerticalStrut()
betweenthe buttons, as shown below and in the ControlPanel
of this simulation.
您可能不想要Box.createGlue()
,它“根据需要增长以吸收其容器中的任何额外空间。” 相反,请在按钮之间使用,如下所示和本模拟的。Box.createVerticalStrut()
ControlPanel
example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS));
example.add(findNext);
Box.createVerticalStrut(10);
example.add(cancel);
Addendum:
附录:
adding in
setMaximumSize()
made it work.
添加
setMaximumSize()
使其工作。
This is the expected behavior for components having identical maximum widths in a vertical BoxLayout
, as described in Box Layout Features. The preferred width of the container becomes that of the (equally wide) children, and the X alignment becomes irrelevant.
这是在垂直方向具有相同最大宽度的组件的预期行为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);
回答by Tim Stone
As mentioned in the comments on the question, you were able to fix it by switching to setMaximumSize()
. However, as you noted, setPreferredSize()
doesn't work. So, what's up with that?
正如对该问题的评论中所述,您可以通过切换到setMaximumSize()
. 但是,正如您所指出的,setPreferredSize()
不起作用。那么,这是怎么回事?
With many things Swing, the properties used to determine the actual component size when using the BoxLayout
are somewhat random (in my opinion). When determining how to render the components, Swing calls layoutComponent()
on the layout manager, which is figures out where to position everything.
对于 Swing 的许多东西,在使用时用于确定实际组件大小的属性BoxLayout
有些随机(在我看来)。在确定如何呈现组件时,Swing 会调用layoutComponent()
布局管理器,该管理器会确定放置所有内容的位置。
BoxLayout
's implementation of layoutComponent()
involves a call to a method that creates SizeRequirements
objects for the width and height of each of the components you add to the JPanel
, based on their getMinimum/Preferred/MaximumSize()
methods.
BoxLayout
的实现layoutComponent()
涉及调用一个方法,该方法SizeRequirements
为您添加到 的每个组件的宽度和高度创建对象JPanel
,基于它们的getMinimum/Preferred/MaximumSize()
方法。
Later, it calls SizeRequirements.calculateAlignedPositions()
for determining the correct width values for each component, because your orientation is BoxLayout.Y_AXIS
(The heights are calculated using a different method). Taking snippets from the source, the relevant implementation of this method is as follows:
稍后,它需要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);
}
Note that totalDescent
is the available width, so descent
is always set to maxDescent
, which is based on SizeRequirements.maximum
, which was taken from JButton.getMaximumSize()
. The value of spans[i]
is then used later in a call to JButton.setBounds()
as the width. As you'll note, getPreferredSize()
was never involved here, which is why setting it has no impact in this case.
请注意,这totalDescent
是可用宽度,因此descent
始终设置为maxDescent
,它基于SizeRequirements.maximum
,取自JButton.getMaximumSize()
。spans[i]
然后在调用 to 时使用的值JButton.setBounds()
作为宽度。正如您将注意到的,getPreferredSize()
这里从未涉及,这就是为什么在这种情况下设置它没有影响。
回答by Denis Tulskiy
Usually if want to ensure a size of the component in Swing you need to call setMinimumSize()
, setMaximumSize()
, and SetPrefferedSize()
with the same value.
通常,如果想要确保一个尺寸在Swing组件的需要调用setMinimumSize()
,setMaximumSize()
以及SetPrefferedSize()
使用相同的值。
回答by Lesya Makhova
button.setMaximumSize(getMaximumSize());
回答by Denizen
If you put your buttons in a GridLayout panel they will be the same width.
如果您将按钮放在 GridLayout 面板中,它们的宽度将相同。