0

My GUI has a button that allows me to put a new JTextField into an arraylist and then put it on my GUI. I wanted to also create another button that removes the last JTextField on the arraylist. My ActionListener for my "Remove" button has the following code

   private class Remover implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            remove(listOfTextFields.get(listOfTextFields.size()));
            pack();
            invalidate();
            repaint();
        }
    }

I expected it to just remove the last instance of the JTextField that was made but I get an IndexOutofBoundsException with the index # out of bounds for length #. # being however many JTextFields I've added. I thought I was in bounds and it would remove the last JTextField on my arraylist but I guess my logic isn't right.

I tried writing down remove(listOfTextFields.get(listOfTextFields.size()-1)); which allowed me to remove one box but I can't keep clicking on the "Remove" button to do more. What am I missing?

Here's the full code for your reference:

public class TheGUI extends JFrame {
    List<JTextField> listOfTextFields = new ArrayList<JTextField>();
    List<String> wordsToChoose = new ArrayList<String>();

    private JTextField instruct;
    private JButton submit;
    private JButton addNew;
    private TheGUI frame;
    private Random r = new Random();
    private JButton remove;

    public TheGUI() { //My GUI with the default fields & buttons that should be on there.
        super("Chili");
        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        instruct = new JTextField("Choose your words");
        instruct.setEditable(false);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 0;
        c.gridy = 0;
        add(instruct, c);

        addNew = new JButton("Add");
        c.weightx = 0.0;
        c.gridx = 1;
        c.gridy = 0;
        add(addNew, c);


        remove = new JButton("Remove");
        c.weightx = 0.0;
        c.gridx= 2;
        c.gridy = 0;
        add(remove, c);

        submit = new JButton("Submit!");
        c.weightx = 0.5;
        c.gridwidth = 3;
        c.gridx = 0;
        c.gridy = GridBagConstraints.PAGE_END;
        add(submit, c);

        addNew.addActionListener(new Adder());
        submit.addActionListener(new Randomizer());
        remove.addActionListener(new Remover());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 300);
        setVisible(true);

    }

    private class Adder implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {

            JTextField textfield = new JTextField();

            listOfTextFields.add(textfield);
            GridBagConstraints textFieldConstraints = new GridBagConstraints();
            textFieldConstraints.fill = GridBagConstraints.HORIZONTAL;
            textFieldConstraints.weightx = 0.5;
            textFieldConstraints.gridx = 0;
            textFieldConstraints.gridwidth = 4;
            textFieldConstraints.gridy = listOfTextFields.size();

            add(textfield, textFieldConstraints);
            pack();
            revalidate();
            repaint();

        }
    }

    private class Remover implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            remove(listOfTextFields.get(listOfTextFields.size()));
            pack();
            invalidate();
            repaint();
        }
    }
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Norfe
  • 15
  • 3

1 Answers1

1

You have forgotten to remove the JTextField from the list in the Remover. By doing so, he wants to remove the same element every time you click again, but it is already no longer in the GUI, only in the list.

The IndexOutOfBoundsException comes from the fact that the indexing of the list start at 0. For example, if the list contains one value, then .size() returns 1. So the way to use .size() - 1 is already correct.

More informations about indexing you can find here.

Try this implementation, it should work.

private class Remover implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        remove(listOfTextFields.get(listOfTextFields.size()-1));
        listOfTextFields.remove(listOfTextFields.size()-1)
        pack();
        invalidate();
        repaint();
    }
} 
tgallei
  • 827
  • 3
  • 13
  • 22
  • ohhhhh I thought just removing the component would remove it on the list as well!!! that makes sense now! Thank you so much. Once I gain more knowledge in how to program, I'll definitely help out as much as I can. – Norfe Feb 21 '20 at 15:40