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

Why can't a BoxLayout be shared whereas a FlowLayout can?

我对以下内容感到困惑。

案例A

  1. 将 JFrame 的布局管理器设置为 BoxLayout。
  2. 将 JButton 添加到 JFrame 容器。
  3. 编译。
  4. 运行.
  5. 抛出异常: "Exception in thread "AWT-EventQueue-0" java.awt.AWTError: 无法共享 BoxLayout"

案例 B

  1. 将 JFrame 的布局管理器设置为 FlowLayout。
  2. 将 JButton 添加到 JFrame 容器。
  3. 编译
  4. 运行
  5. 没有抛出异常。

为什么案例A抛出异常而案例B没有?为什么 FlowLayout 和 BoxLayout 在这方面表现不同? "BoxLayout can't be shared" 在案例 A 中是什么意思?

我已经在本网站上阅读了一些关于此异常消息的类似主题,但我仍然对与 FlowLayout 的比较以及异常消息的确切含义感到困惑。

简单回答

基本上,在这种情况下,"BoxLayout can't be shared" 意味着您试图让您的 JFrame 及其 contentPane() 共享同一个 BoxLayout 对象。


进阶说明

当为 JFrame 设置 Layout 时,它会隐式调用 getContentPane().setLayout(manager),因此您实际上是在为 contentPane() 而不是框架本身设置布局。

这让我们了解如何在 BoxLayoutFlowLayout 中检查容器。


FlowLayout

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

BoxLayout

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


这是对后续解释的介绍。

如第一段所述,JFrame.setLayout(LayoutManager) 将调用 JFrame.getContentPane().setLayout(LayoutManager),因此 Layout 设置在 contentPane() 上,后者是 JPanel默认。

查看 BoxLayout(container, int) 的构造函数并问问自己:

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

给它 JFrame 本身是个好主意吗?知道不是Layout上设置的Component?

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

这是实现此目的的正确方法:

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

为什么?

因为我们现在知道容器是 contentPane() 并且最终,例如在添加组件时,将进行检查并检查其中的参数构造函数必须与设置 layout 的组件完全相同 object,例如 FlowLayout 不会发生这种情况。


来源

BoxLayout

FlowLayout