Search code examples
javaindexoutofboundsexceptionjcomponent

Java: IndexOutOfBounds exception and eventDispatch


I apologize if the title is not descriptive of the issue I'm having. I'm developing a testing GUI for a simple GUI calculator. the test GUI would allow the user to click on components of calculator GUI in order to record them. And then start putting values in those components to test the calculator's functionality.

Essentially, I set up three classes MyListener, ThreadRunner and TestGUI. The TestGUI has two buttons, one so that the user can click on the calculator JTextfields and record them using methods in ThreadRunner which has an ArrayList to store JTextFields and other variables to store other components. The other button is to set values into the JTextFields stored in the ArrayList through a method in TestRunner. The problem I'm having is that when I click the second button to set new values I get the exception IndexOutOfBounds along with other ones. I've been banging my head against a wall trying to figure this out for the past couple of days, so any help would be much much appreciated. Thank you!

public class ThreadRunner extends Thread {
//ChooseInput ci = new ChooseInput();
//List<String> inputVal = ci.getInput();

List<JTextField> listOfTextFields = new ArrayList<>();
JTextField output;
JButton goButton;

public void getInputField(JTextField a) {
    listOfTextFields.add(a);
    System.out.println("getinput func. in thread runner works");
    //System.out.println(a);
    System.out.print(listOfTextFields.get(0));
}

public void getOutputField(JTextField a) {
    output = a;
}

public void getButton(JButton a) {
    goButton = a;
}

public void go() {
    for (int i = 0; i < 2; i++) { // to test if go() can access listOfTextFields
        System.out.print(listOfTextFields.get(i));
    }
    listOfTextFields.get(0).setText("10");
    listOfTextFields.get(1).setText("20");
    System.out.println("func go() works");
}
}


public class MyListener implements AWTEventListener {
ThreadRunner t = new ThreadRunner();
public MyListener(ThreadRunner t) {
    t = t;
}

@Override
public void eventDispatched(AWTEvent event) {

    if (event.paramString().substring(0, 13).equals("MOUSE_CLICKED")) {
        System.out.println("Click happens");
        Object o = event.getSource();
        if (o.getClass().equals(JTextField.class)) {
            JTextField tf = (JTextField) o;
            if (tf.isEditable()) {
                t.getInputField(tf);
                System.out.println("TR shpuld have a field");
            } else {
                t.getOutputField(tf);
            }
        }

        if (o.getClass().equals(JButton.class)) {
            JButton jb = (JButton) o;
            t.getButton(jb);
        }
    }
}
}

public class TestGUI {

public TestGUI() {
    final ThreadRunner tr = new ThreadRunner();
    final MyListener ml = new MyListener(tr);
    JFrame f1 = new JFrame();
    JButton b1 = new JButton("get locations");
    JButton b2 = new JButton("test");
    f1.setVisible(true);
    f1.setSize(500, 200);

    f1.getContentPane().add(b1, BorderLayout.NORTH);
    f1.getContentPane().add(b2, BorderLayout.SOUTH);

    b1.setVisible(true);
    b2.setVisible(true);

    b1.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent ae) {
            MyGUI gui = new MyGUI();
            gui.setSize(500, 300);
            gui.setVisible(true);
            gui.setLocation(200, 200);

            Toolkit tk = Toolkit.getDefaultToolkit();

            tk.addAWTEventListener(ml, AWTEvent.MOUSE_EVENT_MASK);
        }
    }
    );

    b2.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent ae) {
            tr.go();
        }
    }
    );
}
}

The error is produced when the go() method in ThreadRunner is invoked StackTrace:

run:

Click happens Click happens getinput func. in thread runner works javax.swing.JTextField[,103,12,249x41,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b97bc3,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]TR shpuld have a field Click happens getinput func. in thread runner works javax.swing.JTextField[,103,12,249x41,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b97bc3,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]TR shpuld have a field Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 Click happens at java.util.ArrayList.rangeCheck(ArrayList.java:653) at java.util.ArrayList.get(ArrayList.java:429) at ThreadRunner.go(ThreadRunner.java:43) at TestGUI$2.actionPerformed(TestGUI.java:55) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) at java.awt.Component.processMouseEvent(Component.java:6525) at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) at java.awt.Component.processEvent(Component.java:6290) at java.awt.Container.processEvent(Container.java:2234) at java.awt.Component.dispatchEventImpl(Component.java:4881) at java.awt.Container.dispatchEventImpl(Container.java:2292) at java.awt.Component.dispatchEvent(Component.java:4703) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462) at java.awt.Container.dispatchEventImpl(Container.java:2278) at java.awt.Window.dispatchEventImpl(Window.java:2750) at java.awt.Component.dispatchEvent(Component.java:4703) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:751) at java.awt.EventQueue.access$500(EventQueue.java:97) at java.awt.EventQueue$3.run(EventQueue.java:702) at java.awt.EventQueue$3.run(EventQueue.java:696) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86) at java.awt.EventQueue$4.run(EventQueue.java:724) at java.awt.EventQueue$4.run(EventQueue.java:722) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) at java.awt.EventQueue.dispatchEvent(EventQueue.java:721) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)


Solution

  • The problem here is that you used

    ThreadRunner t = new ThreadRunner();
    public MyListener(ThreadRunner t) {
        t = t;
    }
    

    which basically assigns the argument to itself instead of the local variable you defined above. By using this you explicitly specify that you d'like to reference the instance variable t instead of the argument. So either use

    ThreadRunner t = new ThreadRunner();
    public MyListener(ThreadRunner t) {
        this.t = t;
    }
    

    Or rename your class variable to another name, e.g.

    ThreadRunner ct = new ThreadRunner();
    public MyListener(ThreadRunner t) {
        ct = t;
    }