Search code examples
javaswinglayout-managerboxlayout

I can't get BoxLayout's setPreferredSize() method to work the way I want it to


I think I solved my problem, but I don't know why it works this way, so I'm hoping someone can explain it to me so I don't do the same mistake again in the future.

Here's a quick example that is compilable of what I'm trying to do:

public class BoxLayoutTest extends JFrame
{
  public BoxLayoutTest()
  {
    setSize(400,300);
    JPanel mainPanel = new JPanel(new FlowLayout());
    setContentPane(mainPanel);

    JPanel subPanel = new JPanel();
    subPanel.setLayout(new BoxLayout(subPanel, BoxLayout.PAGE_AXIS));
    subPanel.setBackground(Color.BLUE);

    JLabel labelTest = new JLabel("This is a test");
    subPanel.add(labelTest);

    labelTest.setPreferredSize(new Dimension(150, 20));
    mainPanel.add(subPanel);
    System.out.println(mainPanel.getSize());
  }

  public static void main( String[] args )
  {
    BoxLayoutTest testFrame = new BoxLayoutTest();
    testFrame.setVisible(true);
  }
}

At first, I had problems with the panel containing the JLabel not resizing like it should with the preferred size. I found out that it was because I was using some variation of mainPanel.getSize() as a preferred size for my subpanels. In this example, I'm using actual number values, which work.

The reason why it didn't work the old way (and that's actually the thing I'd like someone to explain), is why, as seen in the SOP line, mainPanel.getSize() returns a width and a height of 0 while it clearly takes the whole screen, which is 400x300.

Thanks @camickr for telling me I shouldn't set a preferredSize for my Panels, this helped me figure out where the problem was coming from.


Solution

  • Why [does] mainPanel.getSize() returns a width and a height of 0?

    Until pack() "causes this Window to be sized to fit the preferred size and layouts of its subcomponents," the dimensions will be zero.

    System.out.println(mainPanel.getSize());
    this.pack();
    System.out.println(mainPanel.getSize());
    

    Console:

    java.awt.Dimension[width=0,height=0]
    java.awt.Dimension[width=160,height=30]