javamultithreadingswingeventsswingutilities

Cannot call method from the event dispatcher thread


I'm writing a program that records user mouse movement and clicks, and the plays them using the Robot class.

I am running into this error:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalThreadStateException: Cannot call method from the event dispatcher thread

I have read all about the EDT and people keep mentioning that to you must run it in another Thread in-order to exit the EDT.

My question is: why doesn't my code work even though I used a new thread?

Here's the code:

void doAction(Robot robert) {
    int x = ((MouseEvent) event).getXOnScreen();
    int y = ((MouseEvent) event).getYOnScreen();
    Thread safe = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println(SwingUtilities.isEventDispatchThread());
            MouseEvent m = (MouseEvent) this.event; // event is the recording of the click
            robert.mouseMove(x, y); // error traces back to here
            leftClick(robert);
        }
    });
    safe.run();
}

System.out.println(SwingUtilities.isEventDispatchThread()); prints true

The entire class code is here:

class RoboMouseClick extends RoboAction {

    AWTEvent event;

    public RoboMouseClick(String mouse, int MOUSE_MOVE, AWTEvent event,
            long timeStamp) {
        super(mouse, MOUSE_MOVE, timeStamp);
        this.event = event;
    }

    private void leftClick(Robot robot)
    {
        robot.mousePress(InputEvent.BUTTON1_MASK);
        robot.delay(200);
        robot.mouseRelease(InputEvent.BUTTON1_MASK);
        robot.delay(200);
    }

    void doAction(Robot robert) {
        int x = ((MouseEvent) event).getXOnScreen();
        int y = ((MouseEvent) event).getYOnScreen();
        Thread safe = new Thread(() -> {
            System.out.println(SwingUtilities.isEventDispatchThread());
            MouseEvent m = (MouseEvent) event;
            robert.mouseMove(x, y);
            leftClick(robert);
        });
        safe.run();
    }
}

Solution

  • You have to call the method:

    Thread t = new Thread();
    t.start();
    

    instead of

    t.run();
    

    otherwise no new thread will be started and you would be executing the run Method in the same Thread