Search code examples
javaswingawtrobot

Robot class, mouseMove in infinite loop


I have a jbutton which I want, as soon as it's clicked to make an infinite loop of a mouseMove by a robot class. Then, to be stopped when it is clicked again. Problem is in my code when I press it for the first time, it causes the system to freeze and nothing happens when I click it again. I use:

boolean go = false

  jb.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            go = !go;
            if (go)
                jb.setText("Stop!");
            else
                jb.setText("Start!");
            try {
                Robot robot = new Robot();
                while (go) {
                    robot.mouseMove(500, 500);
                    robot.delay(1000);
                    robot.mouseMove(500, 400);
                }
            } catch (AWTException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    });

Solution

  • Swing is a single threaded environment. This means that if anything should block this thread, Swing will be unable to respond to new events, including paint requests and it will appear that you UI has been frozen...because it has...

    Take a look at Concurrency in Swing

    The simplest solution might be to spawn a new thread and run your loop within it...

    Start by writing a Runnable that handels the work you want done...

    public class MouseRunner implements Runnable {
    
        @Override
        public void run() {
            try {
                Robot robot = new Robot();
                while (go) {
                    robot.mouseMove(500, 500);
                    robot.delay(1000);
                    robot.mouseMove(500, 400);
                }
            } catch (AWTException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }
    

    Then when the user first clicks the button, create a Thread and start it...

    jb.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            go = !go;
            if (go) {
                jb.setText("Stop!");
                Thread t = new Thread(new MouseRunner());
                t.start();
            } else {
                jb.setText("Start!");
            }
        }
    });
    

    Beware, your go variable is likely going to need to made volatile