Java.awt.AWTError: BoxLayout无法共享

16
我在设置布局之前初始化了MotePanel、Command Panel和LEDPanel,为什么会出现这个异常呢?
请帮忙解决。
Exception in thread "main" java.awt.AWTError: BoxLayout can't be shared
    at javax.swing.BoxLayout.checkContainer(BoxLayout.java:462)
    at javax.swing.BoxLayout.invalidateLayout(BoxLayout.java:246)
    at javax.swing.BoxLayout.addLayoutComponent(BoxLayout.java:279)
    at java.awt.Container.addImpl(Container.java:1107)
    at java.awt.Container.add(Container.java:974)
    at javax.swing.JFrame.addImpl(JFrame.java:556)
    at java.awt.Container.add(Container.java:377)
    at Window.<init>(Window.java:54)

public class Window extends JFrame{
    private JPanel MotePanel;
    private JPanel LEDPanel;
    private JPanel CommandPanel;
    private JCheckBox motes[];
    private JRadioButton Leds[];

    public Window(){
        this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
        this.setTitle("Sensor Networks Lab");
        this.setSize(300, 200);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        MotePanel = new JPanel();
        LEDPanel = new JPanel();
        CommandPanel = new JPanel();
        motes = new JCheckBox[10];
        Leds = new JRadioButton[3];


        MotePanel.setLayout(new BoxLayout(MotePanel, BoxLayout.Y_AXIS));
        CommandPanel.setLayout(new BoxLayout(CommandPanel, BoxLayout.Y_AXIS));
        LEDPanel.setLayout(new BoxLayout(LEDPanel, BoxLayout.Y_AXIS));

        System.out.println("creating MotePanel");
        for(int i=0; i<10; i++){
            motes[i] = new JCheckBox("Mote "+i);
            MotePanel.add(motes[i]);
        }


        System.out.println("creating LEDPanel");
        for(int i=0; i<3; i++)
            Leds[i] = new JRadioButton();
        Leds[0].setText("RED");
        LEDPanel.add(Leds[0]);
        Leds[1].setText("GREEN");
        LEDPanel.add(Leds[1]);
        Leds[2].setText("BLUE");
        LEDPanel.add(Leds[2]);

        this.add(MotePanel);
        this.add(LEDPanel);
        this.add(CommandPanel);
    }

我尝试了this.getContentPane().add(MotePanel),但仍然出现相同的错误...我不知道我在这里做错了什么。此外,我还尝试了this.add(MotePanel)。 - anupash
3个回答

48

调用JFrame的setLayout方法时,实际上是将布局添加到JFrame的contentPane而不是JFrame本身,因为该方法更像是一个方便方法,会将方法调用传递给contentPane。BoxLayout构造函数必须反映这一点,因为您无法将BoxLayout添加到一个容器中,然后将其作为参数传递给另一个容器。所以请将此更改为:

this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));

变为这样:

setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS));

另外:不需要使用this.,因为这个关键字是隐含的。在此处也没有实际的需要扩展JFrame。

编辑:下面的代码就足以演示你的错误和解决方案:

import javax.swing.*;

public class BoxLayoutFoo extends JFrame {
   public BoxLayoutFoo() {

      // swap the comments below
      setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS)); // comment out this line
      //setLayout(new BoxLayout(getContentPane(), BoxLayout.LINE_AXIS)); // uncomment this line

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      pack();
      setVisible(true);
   }

   public static void main(String[] args) {
      new BoxLayoutFoo();
   }
}

但我正在为MotePanel、LEDPanel和CommandPanel设置布局,而不是为"this"设置布局。我应该做哪些确切的更改才能消除错误... - anupash
@anupash:请运行您的代码并检查是哪一行引起了错误。这将会解释很多问题,让您更加清晰明了。 - Hovercraft Full Of Eels
我甚至注释掉了MotePanel.setLayout,LEDPanel.setLayout和CommandPanel.setLayout,但仍然出现相同的异常... - anupash
@anupash:请再次检查哪一行导致了错误。 - Hovercraft Full Of Eels
@Hovercraft.. @MByD 谢谢,它起作用了... 我还必须为窗口设置setLayout才能使它工作。 - anupash
显示剩余5条评论

6
你应该将BoxLayout设置在JFrame的contentPane上,而不是JFrame本身 -
this.setLayout(new BoxLayout(this.getContentPane(),BoxLayout.X_AXIS));

代替
this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));

2
+1 - 较慢但通常是正确的。 - Hovercraft Full Of Eels

0

我相信这会让事情更清晰,只需尽量明确您的代码:

this.getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));

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