Question

I am trying to align a number of elements along a vertical axis in the center of a panel, and BoxLayout seems to be just what I need. However, it seems to do strange things when all the elements added have odd-numbered widths.

Here is a SSCCE that demonstrates this screwy behavior:

import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.JFrame;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.BoxLayout;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Component;

public class BoxBug {
  public static void main(String[] args){
    UIManager.put("swing.boldMetal", Boolean.FALSE);
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
        gui();
      }
    });
  }

  public static void gui(){
    JFrame f = new JFrame("Title");
    Box b = new Box(BoxLayout.Y_AXIS);

    JComponent c = new JComponent(){
      public void paint(Graphics g){
        g.setColor(new Color(255, 0, 0));
        g.fillRect(0, 0, getWidth(), getHeight());
      }

      // just change the first argument here
      // (even numbers work fine, odd ones fail)
      private Dimension p = new Dimension(3, 20);
      public Dimension getPreferredSize(){return p;}
      public Dimension getMinimumSize(){return p;}
      public Dimension getMaximumSize(){return p;}
    };
    c.setAlignmentX(Component.CENTER_ALIGNMENT);

    b.add(c);
    f.add(b);
    f.pack();
    f.setVisible(true);
  }
}

This is what it looks like:

enter image description here

When I change the width of the JComponent from 3 to 4, it works fine:

enter image description here

Then it fails again when I change the width to 5:

enter image description here

I've searched on Google and StackOverflow for this issue, but haven't found any documentation on this, so it seems to me like a bug.

If it is a bug, can someone find a hack to get around it?

Was it helpful?

Solution

However, it seems to do strange things when all the elements added have odd-numbered widths.

It gets stranger than that. The size of the parent container also affects the layout.

I replaced the f.pack() with:

f.setSize(150, 100);

and it doesn't work. This is basically the scenario you described since this method or the f.pack() will result in the parent container to have an even width and the layout doesn't work.

However, if you use:

f.setSize(151, 100);

the parent container has an odd width and the layout does work properly.

Another strange observation. I tried adding multiple components to the Box. The problem only seems to happen when the last component added has an odd width.

Anyway, I have no idea what the box layout is doing, but it sure seems like a bug to me.

The solution is to use a different layout manager. You can use a GridBagLayout to display components on different rows. You will need to set the constraint for each component to go to a new row.

Or you could try to use the Relative Layout, which support vertical layout with centered alignment and you don't need any constraints. The only change to your code would be:

//Box b = new Box(BoxLayout.Y_AXIS);
JPanel b = new JPanel( new RelativeLayout(RelativeLayout.Y_AXIS) );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top