大多数布局管理器都没有参数构造函数(也就是说,您可以使用new FlowLayout ()
创建FlowLayout,使用new GridLayout ()
创建GridLayout,使用new GridBagLayout ()
创建GridBagLayout等等。但是,BoxLayout
要求您传递它将要管理的容器以及应该布置组件的轴。
我的问题是:既然您已经告诉布局管理器要布局哪个组件,为什么还需要编写
BoxLayout bl = new BoxLayout(myPanel, BoxLayout.Y_AXIS);
myPanel.setLayout(bl);
而不仅仅是第一行?
我快速浏览了the BoxLayout
source code并看到我使用的构造函数(第178-185行)没有调用target.setLayout(this)
或任何类型的东西。看起来添加它真的很简单。有没有理由不将它包含在Swing库中?
如果重要,我使用
java version 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);
}
}
答案 0 :(得分:5)
Container
必须存在才能传递给BoxLayout
。通常一个人写这样的东西:
JPanel myPanel = new JPanel();
BoxLayout bl = new BoxLayout(myPanel, BoxLayout.Y_AXIS);
myPanel.setLayout(bl);
结合最后两行是很诱人的,但是最不惊讶的原则表明布局的构造函数不应该改变容器的状态。
通常,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);
答案 1 :(得分: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(),它会重置其缓存的详细信息。其他布局实现遵循相同的模式。例如,GroupLayout和OverlayLayout在其构造函数中也需要容器参数。