javaarraysswinglayout-managergrid-layout

Java IllegalArgumentException when assigning array of buttons to GridLayout


So I have started a calculator from scratch in order to practice Java knowledge. I have a slight problem, when I'm assigning buttons to a JLabel using GridLayout the console returns an exception java.lang.IllegalArgumentException. I know I am doing something foolish and I better reorganize the array and do a for loop to assign buttons, but I am too lazy to do it and want to understand what I did wrong.

Here is the code:

buttonDisplay.setBounds(30, 30, 400, 320); //buttonDisplay is a JLabel
buttonDisplay.setLayout(new GridLayout(5,4,5,5));
        
operator = new JButton[20];
operator[0] = new JButton("0");
operator[1] = new JButton("1");
operator[2] = new JButton("2");
operator[3] = new JButton("3");
operator[4] = new JButton("4");
operator[5] = new JButton("5");
operator[6] = new JButton("6");
operator[7] = new JButton("7");
operator[8] = new JButton("8");
operator[9] = new JButton("9");
operator[10] = new JButton("+");
operator[11] = new JButton("-");
operator[12] = new JButton("*");
operator[13] = new JButton("/");
operator[14] = new JButton(".");
operator[15] = new JButton("=");
operator[16] = new JButton("AC");
operator[17] = new JButton("C");
operator[18] = new JButton("TAX+");
operator[19] = new JButton("TAX-");

buttonDisplay.add(operator[0],4,2); //exception starts on this line
buttonDisplay.add(operator[1],3,3);
buttonDisplay.add(operator[2],3,2);
buttonDisplay.add(operator[3],3,1);
buttonDisplay.add(operator[4],2,3);
buttonDisplay.add(operator[5],2,2);
buttonDisplay.add(operator[6],2,1);
buttonDisplay.add(operator[7],1,3);
buttonDisplay.add(operator[8],1,2);
buttonDisplay.add(operator[9],1,1);
buttonDisplay.add(operator[10],1,4);
buttonDisplay.add(operator[11],2,4);
buttonDisplay.add(operator[12],3,4);
buttonDisplay.add(operator[13],4,4);
buttonDisplay.add(operator[14],4,1);
buttonDisplay.add(operator[15],4,3);
buttonDisplay.add(operator[16],5,1);
buttonDisplay.add(operator[17],5,2);
buttonDisplay.add(operator[18],5,3);
buttonDisplay.add(operator[19],5,4);

Solution

  • When I ran [part of] your code, the following line threw an exception:

    buttonDisplay.add(operator[0],4,2);
    

    Here is [part of] the stack trace I got:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: illegal component position
        at java.desktop/java.awt.Container.addImpl(Container.java:1115)
        at java.desktop/java.awt.Container.add(Container.java:1033)
    

    The method you are calling is this one:
    public void add(Component comp, Object constraints, int index)

    I assume that you think that the second and third arguments are the row and column positions in the grid – but they are not. GridLayout does not provide the ability to indicate row and column when adding a component. I think that GridBagLayout is probably a more appropriate layout manager for what you are trying to do.

    Also, even though class javax.swing.JLabel inherits from class java.awt.Container, it is not intended to contain JButtons. There are other Swing components that are intended for this purpose, such as javax.swing.JPanel.

    So I suggest replacing JLabel with JPanel and using GridBagLayout.

    Perhaps the following is more in line with what you are trying to achieve.

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class Calculat {
        private JTextField  display;
    
        private void createAndDisplayGui() {
            JFrame frame = new JFrame("Testing JTextField and JPasswordField");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(createDisplay(), BorderLayout.PAGE_START);
            frame.add(createButtons(), BorderLayout.CENTER);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private JPanel createButtons() {
            JPanel buttonDisplay = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.BOTH;
    
            JButton[] operator = new JButton[20];
            operator[0] = new JButton("0");
            operator[1] = new JButton("1");
            operator[2] = new JButton("2");
            operator[3] = new JButton("3");
            operator[4] = new JButton("4");
            operator[5] = new JButton("5");
            operator[6] = new JButton("6");
            operator[7] = new JButton("7");
            operator[8] = new JButton("8");
            operator[9] = new JButton("9");
            operator[10] = new JButton("+");
            operator[11] = new JButton("-");
            operator[12] = new JButton("*");
            operator[13] = new JButton("/");
            operator[14] = new JButton(".");
            operator[15] = new JButton("=");
            operator[16] = new JButton("AC");
            operator[17] = new JButton("C");
            operator[18] = new JButton("TAX+");
            operator[19] = new JButton("TAX-");
    
            gbc.gridx = 2;
            gbc.gridy = 4;
            buttonDisplay.add(operator[0], gbc); //exception starts on this line
            gbc.gridx = 3;
            gbc.gridy = 3;
            buttonDisplay.add(operator[1], gbc);
            gbc.gridx = 2;
            buttonDisplay.add(operator[2], gbc);
            gbc.gridx = 1;
            buttonDisplay.add(operator[3], gbc);
            gbc.gridx = 3;
            gbc.gridy = 2;
            buttonDisplay.add(operator[4], gbc);
            gbc.gridx = 2;
            buttonDisplay.add(operator[5], gbc);
            gbc.gridx = 1;
            buttonDisplay.add(operator[6], gbc);
            gbc.gridx = 3;
            gbc.gridy = 1;
            buttonDisplay.add(operator[7], gbc);
            gbc.gridx = 2;
            buttonDisplay.add(operator[8], gbc);
            gbc.gridx = 1;
            buttonDisplay.add(operator[9], gbc);
            gbc.gridx = 4;
            buttonDisplay.add(operator[10], gbc);
            gbc.gridy = 2;
            buttonDisplay.add(operator[11], gbc);
            gbc.gridy = 3;
            buttonDisplay.add(operator[12], gbc);
            gbc.gridy = 4;
            buttonDisplay.add(operator[13], gbc);
            gbc.gridx = 1;
            buttonDisplay.add(operator[14], gbc);
            gbc.gridx = 3;
            buttonDisplay.add(operator[15], gbc);
            gbc.gridx = 1;
            gbc.gridy = 5;
            buttonDisplay.add(operator[16], gbc);
            gbc.gridx = 2;
            buttonDisplay.add(operator[17], gbc);
            gbc.gridx = 3;
            buttonDisplay.add(operator[18], gbc);
            gbc.gridx = 4;
            buttonDisplay.add(operator[19], gbc);
            return buttonDisplay;
        }
    
        private JPanel createDisplay() {
            JPanel displayPanel = new JPanel();
            display = new JTextField(16);
            display.setFocusable(false);
            displayPanel.add(display);
            return displayPanel;
        }
    
        public static void main(String[] args) {
            Calculat calc = new Calculat();
            EventQueue.invokeLater(() -> calc.createAndDisplayGui());
        }
    }
    

    This is what is displayed when running the above code.

    screen capture of GUI