为什么BoxLayout不能共享,而FlowLayout可以?

6
我对以下内容感到困惑。
情况A:
  1. 将JFrame的布局管理器设置为BoxLayout。
  2. 将JButton添加到JFrame容器中。
  3. 编译。
  4. 运行。
  5. 抛出异常:“Exception in thread "AWT-EventQueue-0" java.awt.AWTError: BoxLayout can't be shared”。
情况B:
  1. 将JFrame的布局管理器设置为FlowLayout。
  2. 将JButton添加到JFrame容器中。
  3. 编译。
  4. 运行。
  5. 没有抛出异常。
为什么情况A会抛出异常而情况B不会?为什么FlowLayout和BoxLayout在这方面的行为不同?情况A中的“BoxLayout can't be shared”是什么意思?
我已经阅读了一些类似的帖子,但仍然对与FlowLayout的比较和异常消息的确切含义感到困惑。
1个回答

5

简单的回答

基本上,在这种情况下,"BoxLayout不能共享"的意思是你试图让你的JFrame和其contentPane()共享同一个BoxLayout对象。


高级解释

在为JFrame设置Layout时,它隐式地调用getContentPane().setLayout(manager), 所以实际上是为contentPane()设置了布局,而不是为框架本身设置。

这带我们来谈谈BoxLayoutFlowLayout中如何检查容器的问题。


FlowLayout

这个布局没有一个将容器作为参数的构造函数,因此在创建对象时不会考虑容器。该类也没有container的实例变量。

BoxLayout

BoxLayout相反,有一个以容器作为参数的构造函数,并将其存储在实例变量target中。这样做是为了稍后在layoutContainer(container)方法中检查它。它有一个checkContainer(container)方法,将验证实例变量是否等于参数中给定的容器。如果不是,则会抛出throw new AWTError("BoxLayout can't be shared");


这是以下解释的介绍。

如第一段所述,JFrame.setLayout(LayoutManager)将调用JFrame.getContentPane().setLayout(LayoutManager),因此布局设置在默认情况下为JPanelcontentPane()上。

查看BoxLayout(container, int)的构造函数并思考:

现在我知道布局设置在JPanel (contentPane()) 上而不是JFrame本身上,我应该给这个构造函数哪个参数?

JFrame自身作为参数是否是一个好主意?知道它不是布局已设置的组件吗?

答案是:当然不是一个好主意。

以下是正确的实现方式:

JFrame frame = new JFrame();
frame.setLayout(new BoxLayout(frame.getContentPane(), ...);

为什么?

因为我们现在知道容器是 contentPane(),并且当添加组件时,将会进行检查,构造函数中的参数必须是设置了 layout 的组件上的相同 object,而这不会发生在例如 FlowLayout 中。


来源

BoxLayout

FlowLayout


感谢Yassin Hajaj的回答。 - danger mouse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接