Why do you need to invoke setLayout with BoxLayout?

boxlayout, java, layout, layout-manager, swing

Solution

The `Container` must exist before it can be passed to `BoxLayout`. Typically one writes something like this:

JPanel myPanel = new JPanel();
BoxLayout bl = new BoxLayout(myPanel, BoxLayout.Y_AXIS);
myPanel.setLayout(bl);

It's tempting to combine the last two lines, but the principle of least astonishment suggests that the layout's constructor should not otherwise alter the container's state.

Convenienly, `javax.swing.Box` provides "A lightweight container that uses a `BoxLayout` object as its layout manager."

public class Box extends JComponent implements ... {

    public Box(int axis) {
        super();
        super.setLayout(new BoxLayout(this, axis));
    }
}

Now a single line will do:

Box myBox = new Box(BoxLayout.Y_AXIS);

Problem

Most layout managers have no-argument constructors (that is, you can create a FlowLayout with `new FlowLayout ()`, a GridLayout with `new GridLayout ()`, a GridBagLayout with `new GridBagLayout ()`, etc.). However, `BoxLayout` requires that you pass both the container that it will be managing and the axis along which the components should be laid out. My question is: since you're already telling the layout manager which component to lay out, why do you need to write ``` BoxLayout bl = new BoxLayout(myPanel, BoxLayout.Y_AXIS); myPanel.setLayout(bl); ``` instead of just the first line? I took a quick look at the `BoxLayout` source code and saw that the constructor I use (lines 178-185) doesn't make a call to `target.setLayout(this)` or anything of the sort. It seems like it would be really simple to just add that. Is there a reason why it's not included in the Swing library? If it matters, I'm using java version 1.7.0 Java(TM) SE Runtime Environment (build 1.7.0-b147) on Win7Pro. Thanks! SSCCE: ``` import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JButton; public class BoxLayoutSSCCE extends JFrame { // Change this to see what I mean public static final boolean CALL_SET_LAYOUT = true; public BoxLayoutSSCCE () { super("Box Layout SSCCE"); JPanel panel = new JPanel(); BoxLayout bl = new BoxLayout(panel, BoxLayout.Y_AXIS); if (CALL_SET_LAYOUT) { panel.setLayout(bl); } panel.add(new JButton("Button 1")); panel.add(new JButton("Button 2")); } public static void main (String[] args) { BoxLayoutSSCCE blsscce = new BoxLayoutSSCCE(); blsscce.pack(); blsscce.setVisible(true); } } ```

Original source

Related problems