Question

OK, several questions about the test code below... I don't have the full working program to post, but I'm hoping people know Swing well enough to take a stab at it. This is a JLabel inside of a JPanel(BoxLayout), and I'm working on the sizing of the label in the lower right.

What I get with the code as shown is a status box 300 width by 30 height. I have fiddled with the preferred size and the label minimum size, and it does not seem to behave in any rational way.

  1. Why does the JPanel Preferred Size affect the height but not the width? If I change the x dimension in setPreferredSize() to 0 or 500, it still comes out 300 from the label.
  2. Why does the JLabel Minimum Size affect the width but not the height? If I comment the setPreferredSize() call and increase the label height to 30, nothing happens.
  3. I started out with JPanel setMinimumSize (commented), but it no longer has any effect - why does the JPanel require setPreferredSize()?
  4. If I change the label text from "" to " ", this increases the height of the label. Since the label is not controlling the height here, why does this have any effect at all?

By the way, the createRigidArea() call is to force the separator to the right, rather than sticking to the left hand side of the screen. If there are any less kludgy ideas for this, I'd be grateful.

    private JComponent makeStatusBarTest() {
    JPanel statusPanel = new JPanel();
    statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.LINE_AXIS));
    statusPanel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
//  statusPanel.setMinimumSize(new Dimension(0, 30));
    statusPanel.setPreferredSize(new Dimension(500, 30));
    JLabel statusLabel = new JLabel();
    Border emptyBorder = BorderFactory.createEmptyBorder(5, 10, 5, 10);
    statusLabel.setBorder(emptyBorder);
    statusLabel.setText("");
    statusLabel.setMinimumSize(new Dimension(300, 20));
    statusPanel.add(statusLabel);
    statusPanel.add(new JSeparator(SwingConstants.VERTICAL));
    statusPanel.add(Box.createRigidArea(new Dimension(5000,0)));

    return statusPanel;
}
Was it helpful?

Solution

I can explain #1 and #2:

From the BoxLayout javadocs: "BoxLayout attempts to arrange components at their preferred widths (for horizontal layout) or heights (for vertical layout)."

In other words, BoxLayout uses the internal components (in your case, statusLabel) to decide the widths, but the JPanel itself (within reason) to decide the heights.

You can usually use Glue instead of RigidArea to move stuff around, but I agree that it takes some getting used to.

#4 is Swing being too efficient - if the JLabel is empty the text rectangle is 0x0. Ultimately determined in SwingUtilities.layoutCompoundLabelImpl().

I think #3 is because BoxLayout is trying to respect the preferred size of the internal components. Since setMinimumSize, arguably, overrides their preferred sizes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top