Search code examples
javaswinglayout-managergridbaglayoutillegalargumentexception

Positioning components in java GridBagLayout


I am relatively new to Java and I am making an app that helps me estimate construction costs. I built the backend for it, but the buttons and text fields were all in one row, making the app so wide it didn't fit in my screen. I am now trying to use a 3x6 grid bag layout to organize the components like this:

      Title
question1  *answer*
question2  *answer*
question3  *answer*
question4  *answer*
  --Calculate--
Estimate:    $***

When I run the program, I am given an "illegal component position" error (pasted at the bottom) and nothing pops up anymore since I started adding in the grid constraints. The problem is not with the JButton or its action listener. Here is the code, sorry for the lack of comments:

import java.util.*;
import packagepackage.HintTextFieldUI; 
import java.awt.*;
import java.awt.event.*;
import java.security.PublicKey;

import javax.swing.*;
import javax.swing.text.JTextComponent;
public class CP_GUI extends JFrame {
    
    public JLabel tLabel;
    
    public JTextField linear; 
    public JLabel liLabel;
    
   public JComboBox<String> sump; 
   public JLabel suLabel;
   
   public JComboBox<String> elec; 
   public JLabel elLabel;
   
    public JTextField prep;
    public JLabel prLabel;
    
   public JTextField estimate;
   public JLabel esLabel;
   
     public CP_GUI() { 
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(200, 200, 100, 100));
        GridBagConstraints c = new GridBagConstraints();
        
        String title = "Drain Tile Calculator";
        tLabel = new JLabel(title);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.ipady = 40;
        c.gridwidth = 3;
        c.gridx = 0;
        c.gridy = 0;
        panel.add(tLabel, c);
        frame.setTitle(title);

        liLabel = new JLabel("Basement Perimeter Length");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 1;
        c.gridy = 0;
        panel.add(liLabel, c);
        linear = new JTextField(10);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 1;
        c.gridy = 0;
        panel.add(linear, c);
        
        prLabel = new JLabel("Time needed to prepare site:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 2;
        c.gridy = 0;
        panel.add(prLabel, c);
        prep = new JTextField(10);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 2;
        c.gridy = 2;
        panel.add(prep, c);
        
        suLabel = new JLabel("Using:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 3;
        c.gridy = 0;
        panel.add(suLabel, c);
        String[] sumpo = {"New sump pump","Existing sump pump"};
        sump = new JComboBox<>(sumpo);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 3;
        c.gridy = 2;
        panel.add(sump, c);
        
        elLabel = new JLabel("Location of electrical outlet:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 4;
        c.gridy = 0;
        panel.add(elLabel, c);
        String[] electo = {"There is no outlet within 6 feet of the sump pump","There is an outlet nearby, or I do not need a new pump"};
        elec = new JComboBox<>(electo);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 4;
        c.gridy = 2;
        panel.add(elec, c);
      
        estimate = new JTextField(10);
        
        JButton calculate = new JButton("Calculate");
        calculate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event){
                // TODO Auto-generated method stub
                Integer linVar = Integer.parseInt(linear.getText());
                linVar *= 13;
                
                Object sumps = sump.getSelectedItem();
                Integer sumpVar = 0;
                if("New sump pump".equals(sumps)) {
                    sumpVar += 260;}
                
                Object elecs = elec.getSelectedItem();
                Integer elecsVar = 0;
                if("There is no outlet within 6 feet of the sump pump".equals(elecs)) {
                    elecsVar += 280;}
                
                Integer prepsVar = Integer.parseInt(prep.getText());
                prepsVar += 30;
                prepsVar *= 235;
                prepsVar /= 100;
                
                linVar += sumpVar += elecsVar += prepsVar;
                /* overhead*/
                linVar += 2428;
                /* tax */
                linVar *= 11;
                linVar /= 10;
                /* margin */
                linVar *= 12;
                linVar /= 10;
                String toWords = String.valueOf(linVar);
                 
                    estimate.setUI(new HintTextFieldUI(toWords, true));
                    }

        });
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 40;
        c.weightx = 0.5;
        c.gridwidth = 3;
        c.gridx = 5;
        c.gridy = 0;
        panel.add(calculate, c);
        
        esLabel = new JLabel("Estimated Cost:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridwidth = 2;
        c.gridx = 6;
        c.gridy = 0;
        panel.add(esLabel, c);   
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 6;
        c.gridy = 2;
        panel.add(estimate, c); 
        

        frame.add(panel, GridBagConstraints.CENTER);
        
        frame.pack();
        frame.setVisible(true);
        
        linear.setUI(new HintTextFieldUI("Perimeter length", true));
        prep.setUI(new HintTextFieldUI("Minutes of preptime", true));
     }

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

I suspect the issue might either have to with the fact that the size of the grid itself (3x6) is never defined, or with the frame's layout not being properly set to grid bags layout.

Error:

Exception in thread "main" 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)
    at java.desktop/javax.swing.JFrame.addImpl(JFrame.java:554)
    at java.desktop/java.awt.Container.add(Container.java:493)
    at craftsmanPeak/packagepackage.CP_GUI.<init>(CP_GUI.java:163)
    at craftsmanPeak/packagepackage.CP_GUI.main(CP_GUI.java:173)

Thanks so much in advance! I really appreciate it!


Solution

  • frame.add(panel, GridBagConstraints.CENTER); JFrame uses a BorderLayout by default, get rid of the GridBagConstraints.CENTER

    I've also cleaned up you layout (trust me (said some stranger on the internet 🤣), it was a mess)

    You're messing up your x and y positions

    enter image description here

    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public JLabel tLabel;
    
            public JTextField linear;
            public JLabel liLabel;
    
            public JComboBox<String> sump;
            public JLabel suLabel;
    
            public JComboBox<String> elec;
            public JLabel elLabel;
    
            public JTextField prep;
            public JLabel prLabel;
    
            public JTextField estimate;
            public JLabel esLabel;
    
            public TestPane() {
                setLayout(new GridBagLayout());
                setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16));
                GridBagConstraints c = new GridBagConstraints();
    
                String title = "Drain Tile Calculator";
                tLabel = new JLabel(title, JLabel.CENTER);
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 0.5;
                c.ipady = 40;
                c.gridwidth = GridBagConstraints.REMAINDER;
                c.anchor = GridBagConstraints.CENTER;
                c.gridx = 0;
                c.gridy = 0;
                add(tLabel, c);
    
                c = new GridBagConstraints();
                c.anchor = GridBagConstraints.LINE_END;
                c.gridy = 1;
                c.gridx = 0;
    
                liLabel = new JLabel("Basement Perimeter Length:");
                prLabel = new JLabel("Time needed to prepare site:");
                suLabel = new JLabel("Using:");
                elLabel = new JLabel("Location of electrical outlet:");
    
                add(liLabel, c);
                c.gridy++;
                add(prLabel, c);
                c.gridy++;
                add(suLabel, c);
                c.gridy++;
                add(elLabel, c);
    
                linear = new JTextField(10);
                prep = new JTextField(10);
                String[] sumpo = {"New sump pump", "Existing sump pump"};
                sump = new JComboBox<>(sumpo);
                String[] electo = {"There is no outlet within 6 feet of the sump pump", "There is an outlet nearby, or I do not need a new pump"};
                elec = new JComboBox<>(electo);
    
                c.anchor = GridBagConstraints.LINE_START;
    
                c.gridx++;
                c.gridy = 1;
                add(linear, c);
                c.gridy++;
                add(prep, c);
                c.gridy++;
                add(sump, c);
                c.gridy++;
                add(elec, c);
    
                JButton calculate = new JButton("Calculate");
    ////            calculate.addActionListener(new ActionListener() {
    ////                public void actionPerformed(ActionEvent event) {
    ////                    // TODO Auto-generated method stub
    ////                    Integer linVar = Integer.parseInt(linear.getText());
    ////                    linVar *= 13;
    ////
    ////                    Object sumps = sump.getSelectedItem();
    ////                    Integer sumpVar = 0;
    ////                    if ("New sump pump".equals(sumps)) {
    ////                        sumpVar += 260;
    ////                    }
    ////
    ////                    Object elecs = elec.getSelectedItem();
    ////                    Integer elecsVar = 0;
    ////                    if ("There is no outlet within 6 feet of the sump pump".equals(elecs)) {
    ////                        elecsVar += 280;
    ////                    }
    ////
    ////                    Integer prepsVar = Integer.parseInt(prep.getText());
    ////                    prepsVar += 30;
    ////                    prepsVar *= 235;
    ////                    prepsVar /= 100;
    ////
    ////                    linVar += sumpVar += elecsVar += prepsVar;
    ////                    /* overhead*/
    ////                    linVar += 2428;
    ////                    /* tax */
    ////                    linVar *= 11;
    ////                    linVar /= 10;
    ////                    /* margin */
    ////                    linVar *= 12;
    ////                    linVar /= 10;
    ////                    String toWords = String.valueOf(linVar);
    ////
    ////                    estimate.setUI(new HintTextFieldUI(toWords, true));
    ////                }
    ////
    ////            });
    
                c = new GridBagConstraints();
                c.fill = GridBagConstraints.HORIZONTAL;
                c.insets = new Insets(10, 0, 10, 0);
                c.gridwidth = GridBagConstraints.REMAINDER;
                c.gridx = 0;
                c.gridy = 5;
                add(calculate, c);
    
                c = new GridBagConstraints();
                c.gridx = 0;
                c.gridy = 6;
                c.anchor = GridBagConstraints.LINE_END;
    
                esLabel = new JLabel("Estimated Cost:");
                estimate = new JTextField(10);
    
                add(esLabel, c);
    
                c.fill = GridBagConstraints.HORIZONTAL;
                c.gridx = 1;
                add(estimate, c);
    //            linear.setUI(new HintTextFieldUI("Perimeter length", true));
    //            prep.setUI(new HintTextFieldUI("Minutes of preptime", true));
            }
        }
    }