GroupLayout can only be used with one container at a time

Nonconformist picture Nonconformist · Nov 23, 2012 · Viewed 11.2k times · Source

Not sure why this error is coming up. I am using GroupLayout because I want it to do the spacing for me and will be adding more panels to the frame in the future. Below is the stack trace.

Exception in thread "main" java.lang.IllegalArgumentException: GroupLayout can only be used with one Container at a time
    at javax.swing.GroupLayout.checkParent(Unknown Source)
    at javax.swing.GroupLayout.invalidateLayout(Unknown Source)
    at java.awt.Container.invalidate(Unknown Source)
    at java.awt.Component.addNotify(Unknown Source)
    at java.awt.Container.addNotify(Unknown Source)
    at javax.swing.JComponent.addNotify(Unknown Source)
    at java.awt.Container.addNotify(Unknown Source)
    at javax.swing.JComponent.addNotify(Unknown Source)
    at java.awt.Container.addNotify(Unknown Source)
    at javax.swing.JComponent.addNotify(Unknown Source)
    at javax.swing.JRootPane.addNotify(Unknown Source)
    at java.awt.Container.addNotify(Unknown Source)
    at java.awt.Window.addNotify(Unknown Source)
    at java.awt.Frame.addNotify(Unknown Source)
    at java.awt.Window.pack(Unknown Source)
    at client.AlternateGUI.drawGui(AlternateGUI.java:54)
    at client.AlternateGUI.main(AlternateGUI.java:24)

Here is the code:

package client;

import java.awt.Component;*

public class AlternateGUI {
    private JList people;
    private DefaultListModel dlm;
    private JLabel l1, l2, l3;
    private JFrame alternateGUIFrame;
    private final static ImageIcon unavailableIcon = new ImageIcon("offline.png");

    public static void main(String[] args)
    {
        AlternateGUI ls = new AlternateGUI();
        ls.drawGui();
    }

    public AlternateGUI(){
        dlm = new DefaultListModel();
        people = new JList(dlm);

        alternateGUIFrame = new JFrame();

        JScrollPane peopleScroller = new JScrollPane(people, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        people.setCellRenderer(new CellRenderer());

        GroupLayout alternateGUILayout = new GroupLayout(alternateGUIFrame);
        alternateGUIFrame.setLayout(alternateGUILayout);

        alternateGUILayout.setAutoCreateGaps(true);
        alternateGUILayout.setAutoCreateContainerGaps(true);
        alternateGUILayout.setHorizontalGroup(alternateGUILayout.createSequentialGroup()
                .addComponent(peopleScroller));
        alternateGUILayout.setVerticalGroup(alternateGUILayout.createSequentialGroup()
                .addComponent(peopleScroller));
        }

    public void drawGui() {
        l1 = new JLabel("Hi", unavailableIcon , JLabel.LEFT);
        l2 = new JLabel("Hello", unavailableIcon , JLabel.LEFT);
        l3 = new JLabel("Bye", unavailableIcon , JLabel.LEFT);
        dlm.addElement(l1);
        dlm.addElement(l2);
        dlm.addElement(l3);

        alternateGUIFrame.pack();
        alternateGUIFrame.setVisible(true);
    }

    class CellRenderer implements ListCellRenderer
    {
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            Component com = (Component)value;
            return com;
        }
    }
}

Answer

Hovercraft Full Of Eels picture Hovercraft Full Of Eels · Nov 23, 2012

Your problem is that you're unknowingly adding the layout to both the JFrame and its contentPane. The solution is to make sure you add it to the JFrame's contentPane only:

  GroupLayout alternateGUILayout = new GroupLayout(alternateGUIFrame.getContentPane());
  alternateGUIFrame.getContentPane().setLayout(alternateGUILayout);

It's the first line above that matters the most.

Another option is to work with JPanels, and then add the JPanels to the JFrame's contentPane in its default BorderLayout.CENTER position.