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.
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.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/
Usually if want to ensure a size of the component in Swing you need to call
setMinimumSize()
,setMaximumSize()
, andSetPrefferedSize()
with the same value.If you put your buttons in a GridLayout panel they will be the same width.
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.