9

大多数布局管理器都有无参数构造函数(也就是说,您可以创建一个带有 的 FlowLayout new FlowLayout ()、一个带有 的 GridLayout new GridLayout ()、一个带有 的 GridBagLayoutnew GridBagLayout ()等)。但是,BoxLayout这要求您同时传递它将管理的容器和组件应沿其布置的轴。

我的问题是:既然您已经告诉布局管理器要布局哪个组件,为什么还需要编写

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

而不仅仅是第一行?

我快速查看BoxLayout源代码,发现我使用的构造函数(第 178-185 行)没有调用target.setLayout(this)或进行任何类似的调用。添加它似乎真的很简单。Swing 库中没有包含它的原因是什么?

如果重要的话,我正在使用

Java 版本 1.7.0

Java(TM) SE 运行时环境(内部版本 1.7.0-b147)

在 Win7Pro 上。

谢谢!


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);
    }
}
4

2 回答 2

5

Container必须存在才能传递BoxLayout给。通常一个人会这样写:

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

合并最后两行是很有诱惑力的,但最小惊讶原则表明布局的构造函数不应该以其他方式改变容器的状态。

Convenienly,javax.swing.Box提供了“一个使用BoxLayout对象作为其布局管理器的轻量级容器”。

public class Box extends JComponent implements ... {

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

现在一行就可以了:

Box myBox = new Box(BoxLayout.Y_AXIS);
于 2012-06-03T07:41:40.157 回答
4

BoxLayout确保将布局方法应用于正确的容器。它强制在构造函数中指定的相同容器用于各种方法,例如layoutContainer(Container target),preferredLayoutSize(Container target)等。它归结为进行checkContainer()验证的方法:

void checkContainer(Container target) {
    if (this.target != target) {
        throw new AWTError("BoxLayout can't be shared");
    }
}

BoxLayout实现可能会缓存有关容器的一些详细信息并尝试维护状态,因此无法共享。

编辑:

BoxLayout实现LayoutManager2.invalidateLayout()并在其中重置其缓存的详细信息。其他布局实现遵循相同的模式。例如,GroupLayoutOverlayLayout在其构造函数中也需要容器参数。

于 2012-06-03T05:26:21.667 回答