15

I have initialized MotePanel, Command Panel and LEDPanel before setting their Layout, then how so am I getting this exception.

Please help.

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);
    }
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
anupash
  • 302
  • 3
  • 4
  • 10
  • this.add(MotePanel); I tried this.getContentPane().add(MotePanel) even this gives the same error ... I dont know what am I doing wrong here. – anupash May 06 '11 at 21:15

3 Answers3

48

When calling setLayout on a JFrame, you're actually adding the layout to the JFrame's contentPane not the JFrame itself since this method is more of a convenience method that transmits the method call to the contentPane. The BoxLayout constructor must reflect this since you can't add the BoxLayout to one container and then pass in as a parameter a different container. So change this:

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

to this:

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

Also: no need for all the this. business since this. is implied, and also there is no actual need here to extend JFrame.

edit: this code below is all that is needed to demonstrate your error and its solution:

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();
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • But I am setting layout for MotePanel, LEDPanel and CommandPanel and not for "this" What changes should I do exactly to remove the error ... – anupash May 06 '11 at 21:22
  • @anupash: please run your code and check to see which line causes the error. This will explain a lot and make things clearer to you. – Hovercraft Full Of Eels May 06 '11 at 21:24
  • I even comment out the MotePanel.setLayout , LEDPanel.setLayout and CommandPanel.setLayout and still the same exception ... – anupash May 06 '11 at 21:25
  • @anupash: **AGAIN** please check which line causes the error. – Hovercraft Full Of Eels May 06 '11 at 21:25
  • @Hovercraft... it's the line 54 in the my code which is "this.add(MotePanel);" – anupash May 06 '11 at 21:27
  • @anupash: Please run the newest code and double check which line is causing the error, because that's not it. – Hovercraft Full Of Eels May 06 '11 at 21:29
  • Hint: it's the line that MByD and I are trying to get you to correct. Please see the edit to my post. – Hovercraft Full Of Eels May 06 '11 at 21:30
  • @Hovercraft.. @MByD thanx it worked ... I had to setLayout for Window also to get the thing to work – anupash May 06 '11 at 21:37
  • You've **been** trying to set the layout for the Window object, that's what we've been trying to tell you as that is what "this" is. But in actual fact, you really don't set the layout for the Window JFrame but in fact are setting it for its contentPane (as we've been trying to tell you). Do you understand the difference? – Hovercraft Full Of Eels May 06 '11 at 21:41
  • @Hovercraft: I always use a JPanel that is then set as the content pane. One reason is that it is easier to set a border to it (no casting needed) but another large part of it is that it removes all the confusion about whether we are dealing with a content pane or frame. – Andrew Thompson May 07 '11 at 09:49
6

You should set the BoxLayout with the contentPane of the JFrame, not the JFrame itself -

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

instead of

this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
MByD
  • 135,866
  • 28
  • 264
  • 277
0

I believe this will make things more clear, just try to be more explicit about your code: this.getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));

chromechris
  • 215
  • 4
  • 9