为什么不能共享 BoxLayout 而 FlowLayout 可以?
Why can't a BoxLayout be shared whereas a FlowLayout can?
我对以下内容感到困惑。
案例A
- 将 JFrame 的布局管理器设置为 BoxLayout。
- 将 JButton 添加到 JFrame 容器。
- 编译。
- 运行.
- 抛出异常:
"Exception in thread "AWT-EventQueue-0" java.awt.AWTError: 无法共享 BoxLayout"
案例 B
- 将 JFrame 的布局管理器设置为 FlowLayout。
- 将 JButton 添加到 JFrame 容器。
- 编译
- 运行
- 没有抛出异常。
为什么案例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() 而不是框架本身设置布局。
这让我们了解如何在 BoxLayout
和 FlowLayout
中检查容器。
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
不会发生这种情况。
来源
我对以下内容感到困惑。
案例A
- 将 JFrame 的布局管理器设置为 BoxLayout。
- 将 JButton 添加到 JFrame 容器。
- 编译。
- 运行.
- 抛出异常: "Exception in thread "AWT-EventQueue-0" java.awt.AWTError: 无法共享 BoxLayout"
案例 B
- 将 JFrame 的布局管理器设置为 FlowLayout。
- 将 JButton 添加到 JFrame 容器。
- 编译
- 运行
- 没有抛出异常。
为什么案例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() 而不是框架本身设置布局。
这让我们了解如何在 BoxLayout
和 FlowLayout
中检查容器。
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
不会发生这种情况。