我正在尝试让我的 JDialog
的布局适合我要移植到 Java 的程序的特定外观,我之前使用过几个 LayoutManager,并取得了巨大的成功出于某种原因,我似乎根本无法让这个工作。我的目标是让 JDialog 的右(东)侧按自上而下的顺序包含“查找下一个”和“取消”按钮,然后在下面添加任何额外的空间,以便这两个按钮始终位于 JDialog
的顶部,但由于某种原因 BoxLayout
不断忽略任何更改(这是我迷失的地方) 宽度的尝试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
始终保留其正常大小。我尝试使用与 setPreferredSize
相同的参数来使用 setMinimumSize()
和 setMaximumSize()
,但没有成功。我什至尝试过 cancel.setPreferredSize(new Dimension(500, 500));
并且按钮高度是唯一调整的,它仍然保留给定的默认宽度。
为了解决任何问题,这是它的样子(现在我已经完成了),您会看到“查找下一个”和“取消”按钮的大小不同。
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.
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.
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.
发布评论
评论(6)
我知道这是一个老问题,但我真的没有看到一个好的解释。因此,为了偶然发现这一点的搜索者,我将添加我的两分钱。
在 Swing 中存在与调整组件大小相关的三种方法:setPreferredSize()、setMinimumSize() 和 setMaximumSize()。然而,重要的一点是,是否遵循这些方法取决于所使用的特定布局管理器。
对于 BoxLayout(原始海报使用的布局):
BoxLayout
采用此BoxLayout
采用此OP 正在使用 Y_AXIS BoxLayout,这就是为什么只更改了他的高度。
更新:我为所有布局管理器整理了一个包含相同信息的页面。希望它可以帮助一些搜索者: http://thebadprogrammer.com/swing-layout-manager-尺寸/
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.
For BoxLayout (the layout the original poster is using):
BoxLayout
honors thisBoxLayout
honors thisThe OP is using a Y_AXIS BoxLayout which is why only his height was being changed.
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/
您可能不需要
Box.createGlue()
,它“Box .createVerticalStrut()
在按钮之间,如下所示以及ControlPanel
>模拟。附录:
这是垂直
BoxLayout
中具有相同最大宽度的组件的预期行为,如 框布局功能。容器的首选宽度成为(同样宽的)子容器的宽度,并且 X 对齐变得无关紧要。You may not want
Box.createGlue()
, which "grows as necessary to absorb any extra space in its container." Instead, useBox.createVerticalStrut()
between the buttons, as shown below and in theControlPanel
of this simulation.Addendum:
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.正如该问题的评论中提到的,您可以通过切换到 setMaximumSize() 来修复它。但是,正如您所指出的,
setPreferredSize()
不起作用。那么,这是怎么回事呢?对于 Swing 的许多东西,使用 BoxLayout 时用于确定实际组件大小的属性有些随机(在我看来)。当确定如何呈现组件时,Swing 会调用布局管理器上的
layoutComponent()
,该管理器会确定将所有内容放置在何处。BoxLayout
的layoutComponent()
实现涉及对创建SizeRequirements
对象,用于添加到 < 的每个组件的宽度和高度code>JPanel,基于其getMinimum/Preferred/MaximumSize()
方法。稍后,它调用
SizeRequirements.calculateAlignedPositions()
来确定每个组件的正确宽度值,因为您的方向是BoxLayout.Y_AXIS
(高度是使用不同的方法计算的) 。摘取源码,该方法的相关实现如下:注意,
totalDescent
是可用宽度,因此descent
始终设置为maxDescent,它基于
SizeRequirements.maximum
,它取自JButton.getMaximumSize()
。随后在调用JButton.setBounds()
时使用spans[i]
的值作为宽度。正如您将注意到的,这里从未涉及getPreferredSize()
,这就是为什么设置它在这种情况下没有影响。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?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 callslayoutComponent()
on the layout manager, which is figures out where to position everything.BoxLayout
's implementation oflayoutComponent()
involves a call to a method that createsSizeRequirements
objects for the width and height of each of the components you add to theJPanel
, based on theirgetMinimum/Preferred/MaximumSize()
methods.Later, it calls
SizeRequirements.calculateAlignedPositions()
for determining the correct width values for each component, because your orientation isBoxLayout.Y_AXIS
(The heights are calculated using a different method). Taking snippets from the source, the relevant implementation of this method is as follows:Note that
totalDescent
is the available width, sodescent
is always set tomaxDescent
, which is based onSizeRequirements.maximum
, which was taken fromJButton.getMaximumSize()
. The value ofspans[i]
is then used later in a call toJButton.setBounds()
as the width. As you'll note,getPreferredSize()
was never involved here, which is why setting it has no impact in this case.通常,如果要确保 Swing 中组件的大小,您需要调用
setMinimumSize()
、setMaximumSize()
和SetPrefferedSize()
相同的值。Usually if want to ensure a size of the component in Swing you need to call
setMinimumSize()
,setMaximumSize()
, andSetPrefferedSize()
with the same value.如果将按钮放在 GridLayout 面板中,它们将具有相同的宽度。
If you put your buttons in a GridLayout panel they will be the same width.