Tom Magaro
Tom Magaro

Reputation: 167

Getting InvalidStateException when using JComboBox in GroupLayout

I am trying out GroupLayout for the first time. When I just added the components to the containing JPanel, not all components were showing up, but the JComboBox was one of the ones that did show up. After instantiating the components, I used the addComponent method of the GroupLayout API, but when I run the program, I get an InvalidStateException on the JComboBox.

Here is the code

public class PersonalInfo extends JPanel {

    private JLabel jLabel1;
    private JTextField firstName;
    private JTextField lastName;
    private JLabel jLabel2;
    private JTextField address1;
    private JTextField address2;
    private JCheckBox toggleAddress3;
    private JTextField address3;
    private JTextField city;
    private JTextField state;
    private JTextField postalCode;
    private JLabel jLabel3;
    private JComboBox<String> gender;
    private JLabel jLabel4;
//    private Date dateOfBirth;

    /**
     * Creates new form PersonalInfo
     */
    public PersonalInfo() {
        initComponents();
        setPreferredSize(new Dimension(400, 800));
        validate();
    }

    private void initComponents() {
        GroupLayout groupLayout = new GroupLayout(this);
        setLayout(groupLayout);
        groupLayout.setAutoCreateGaps(true);
        groupLayout.setAutoCreateContainerGaps(true);

        jLabel1 = new JLabel("Name");
        jLabel1.setHorizontalAlignment(SwingConstants.RIGHT);

        firstName = new JTextField(50);
        firstName.setToolTipText("First Name");

        lastName = new JTextField(50);
        lastName.setToolTipText("Last Name");

        jLabel2 = new JLabel("Address");
        jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);

        address1 = new JTextField(50);
        address1.setToolTipText("Address 1");

        address2 = new JTextField(50);
        address2.setToolTipText("Address 2");
        add(address2);

        toggleAddress3 = new javax.swing.JCheckBox();
        toggleAddress3.setText("Show third address");
        toggleAddress3.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                setToggle();
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        address3 = new JTextField(50);
        address3.setToolTipText("Address 3");
        address3.setVisible(false);

        city = new JTextField(50);
        city.setToolTipText("City");

        state = new JTextField(10);
        state.setToolTipText("State");

        postalCode = new JTextField(25);
        postalCode.setToolTipText("Postal Code");

        jLabel3 = new JLabel("Gender");
        jLabel3.setHorizontalAlignment(SwingConstants.RIGHT);
        add(jLabel3);

        String[] items = {"", "Male", "Female"};
        gender = new JComboBox<String>(items);
        gender.setToolTipText("Gender");

        jLabel4 = new JLabel("Date of Birth");
        jLabel4.setHorizontalAlignment(SwingConstants.RIGHT);

        groupLayout.setHorizontalGroup(groupLayout.createParallelGroup()
            .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel1)
                .addComponent(firstName)
                .addComponent(lastName))
            .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel2)
                .addComponent(address1))
            .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(toggleAddress3)
                .addComponent(address2))
            .addComponent(address3)
            .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(city)
                .addComponent(state)
                .addComponent(postalCode))
            .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel3)
                .addComponent(gender))
            .addComponent(jLabel4)
        );
        groupLayout.setVerticalGroup(groupLayout.createParallelGroup()
            .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.TRAILING))
            .addComponent(jLabel1)
            .addComponent(jLabel2)
            .addComponent(jLabel3)
            .addComponent(jLabel4));
    }

    private void setToggle() {
        if (toggleAddress3.isSelected()) {
            address3.setVisible(false);
        } else {
            address3.setVisible(true);
        }
        repaint();
    }

}

Any help with this is greatly appreciated.

Scratching my head,

Tom Magaro

Upvotes: 0

Views: 30

Answers (2)

Tom Magaro
Tom Magaro

Reputation: 167

Adding the components to the vertical axis worked.

Upvotes: 0

Abra
Abra

Reputation: 20923

Refer to How to Use GroupLayout.

each component needs to be defined twice in the layout. If you forget to do this, GroupLayout will generate an exception.

You are not adding all your components to both the horizontal group and the vertical group and hence the exception you are getting.

Actually, this is one time where I would suggest actually using the GUI builder of your IDE since GroupLayout was created specifically for GUI builders. After you create your GUI using the builder, look at the [java] code that it generated in order to try to understand how GroupLayout works.

I tried to guess how you want your PersonalInfo panel to look and created one using Eclipse WindowBuilder. For what it's worth, here is the generated code.

Note that I added a JSpinner for the Date of Birth field.

import javax.swing.JPanel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import java.util.Date;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.Calendar;

public class WndwBldr extends JPanel {
    private JLabel nameLabel;
    private JTextField firstNameTextField;
    private JTextField lastNameTextField;
    private JLabel addressLabel;
    private JTextField address1TextField;
    private JTextField address2TextField;
    private JCheckBox toggleAddress3;
    private JTextField address3TextField;
    private JTextField cityTextField;
    private JTextField stateTextField;
    private JTextField postalCodeTextField;
    private JLabel genderLabel;
    private JComboBox<String> genderComboBox;
    private JLabel dateOfBirthLabel;
    private JSpinner dateOfBirthSpinner;

    /**
     * Create the panel.
     */
    public WndwBldr() {
        GroupLayout groupLayout = new GroupLayout(this);
        groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                        .addComponent(getNameLabel())
                        .addComponent(getAddressLabel())
                        .addComponent(getGenderLabel()))
                    .addPreferredGap(ComponentPlacement.RELATED)
                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                        .addComponent(getFirstNameTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(getAddress1TextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(getCityTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(getGenderComboBox(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(ComponentPlacement.UNRELATED)
                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                        .addComponent(getLastNameTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addGroup(groupLayout.createSequentialGroup()
                            .addComponent(getStateTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addComponent(getPostalCodeTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                        .addGroup(groupLayout.createSequentialGroup()
                            .addComponent(getAddress2TextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addComponent(getToggleAddress3())
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addComponent(getAddress3TextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                        .addGroup(groupLayout.createSequentialGroup()
                            .addComponent(getDateOfBirthLabel())
                            .addPreferredGap(ComponentPlacement.UNRELATED)
                            .addComponent(getDateOfBirthSpinner(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                    .addContainerGap(103, Short.MAX_VALUE))
        );
        groupLayout.setVerticalGroup(
            groupLayout.createParallelGroup(Alignment.LEADING)
                .addGroup(groupLayout.createSequentialGroup()
                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
                        .addGroup(groupLayout.createSequentialGroup()
                            .addContainerGap()
                            .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
                                .addComponent(getNameLabel())
                                .addComponent(getLastNameTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addComponent(getFirstNameTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
                                .addComponent(getAddressLabel())
                                .addComponent(getAddress1TextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addComponent(getAddress2TextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addComponent(getToggleAddress3())))
                        .addGroup(groupLayout.createSequentialGroup()
                            .addGap(38)
                            .addComponent(getAddress3TextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                    .addPreferredGap(ComponentPlacement.RELATED)
                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
                        .addComponent(getCityTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(getStateTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(getPostalCodeTextField(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(ComponentPlacement.RELATED)
                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
                        .addComponent(getGenderLabel())
                        .addComponent(getGenderComboBox(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(getDateOfBirthLabel())
                        .addComponent(getDateOfBirthSpinner(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addContainerGap(190, Short.MAX_VALUE))
        );
        setLayout(groupLayout);

    }
    private JLabel getNameLabel() {
        if (nameLabel == null) {
            nameLabel = new JLabel("Name");
        }
        return nameLabel;
    }
    private JTextField getFirstNameTextField() {
        if (firstNameTextField == null) {
            firstNameTextField = new JTextField();
            firstNameTextField.setColumns(10);
        }
        return firstNameTextField;
    }
    private JTextField getLastNameTextField() {
        if (lastNameTextField == null) {
            lastNameTextField = new JTextField();
            lastNameTextField.setColumns(10);
        }
        return lastNameTextField;
    }
    private JLabel getAddressLabel() {
        if (addressLabel == null) {
            addressLabel = new JLabel("Address");
        }
        return addressLabel;
    }
    private JTextField getAddress1TextField() {
        if (address1TextField == null) {
            address1TextField = new JTextField();
            address1TextField.setColumns(10);
        }
        return address1TextField;
    }
    private JTextField getAddress2TextField() {
        if (address2TextField == null) {
            address2TextField = new JTextField();
            address2TextField.setColumns(10);
        }
        return address2TextField;
    }
    private JCheckBox getToggleAddress3() {
        if (toggleAddress3 == null) {
            toggleAddress3 = new JCheckBox("");
        }
        return toggleAddress3;
    }
    private JTextField getAddress3TextField() {
        if (address3TextField == null) {
            address3TextField = new JTextField();
            address3TextField.setColumns(10);
        }
        return address3TextField;
    }
    private JTextField getCityTextField() {
        if (cityTextField == null) {
            cityTextField = new JTextField();
            cityTextField.setColumns(10);
        }
        return cityTextField;
    }
    private JTextField getStateTextField() {
        if (stateTextField == null) {
            stateTextField = new JTextField();
            stateTextField.setColumns(10);
        }
        return stateTextField;
    }
    private JTextField getPostalCodeTextField() {
        if (postalCodeTextField == null) {
            postalCodeTextField = new JTextField();
            postalCodeTextField.setColumns(10);
        }
        return postalCodeTextField;
    }
    private JLabel getGenderLabel() {
        if (genderLabel == null) {
            genderLabel = new JLabel("Gender");
        }
        return genderLabel;
    }
    private JComboBox<String> getGenderComboBox() {
        if (genderComboBox == null) {
            genderComboBox = new JComboBox<>();
            genderComboBox.setModel(new DefaultComboBoxModel<String>(new String[] {"", "male", "female"}));
        }
        return genderComboBox;
    }
    private JLabel getDateOfBirthLabel() {
        if (dateOfBirthLabel == null) {
            dateOfBirthLabel = new JLabel("Date of Birth");
        }
        return dateOfBirthLabel;
    }
    private JSpinner getDateOfBirthSpinner() {
        if (dateOfBirthSpinner == null) {
            dateOfBirthSpinner = new JSpinner();
            dateOfBirthSpinner.setModel(new SpinnerDateModel(new Date(-7200000L), new Date(-2208996000000L), new Date(1610661600000L), Calendar.DAY_OF_YEAR));
        }
        return dateOfBirthSpinner;
    }
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new WndwBldr(), BorderLayout.CENTER);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        });
    }
}

Here is a screen capture.

screen capture of running app

Upvotes: 1

Related Questions