简单回答
基本上,"BoxLayout can't be shared" 在这种情况下意味着您正试图让您的 JFrame 和它的 contentPane() 共享同一个 BoxLayout 对象。
进阶说明
当为JFrame 设置Layout 时,它会隐式调用getContentPane().setLayout(manager),因此您实际上是为 contentPane() 而不是框架本身设置布局。
这让我们了解如何在BoxLayout 和FlowLayout 中检查容器。
FlowLayout
此布局没有将容器作为参数的构造函数,因此在创建对象时不会考虑容器。此类也没有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() 并且最终,例如添加组件时,将进行检查并且构造函数中的参数必须完全相同object 作为在 layout 上设置的组件,例如 FlowLayout 不会发生。
来源
BoxLayout
FlowLayout