0

I am trying to write an application which allow me to turn on and off mouse moving on button click. However, when mouse starting to move whole application freezes and I have to kill it from IDE.

I have tried to put mouse mover to different thread but I have an error:

Exception in thread "Thread-4" java.lang.IllegalStateException: This operation is permitted on the event thread only; currentThread = Thread-4
    at javafx.graphics/com.sun.glass.ui.Application.checkEventThread(Application.java:447)
    at javafx.graphics/com.sun.glass.ui.mac.MacRobot.mouseMove(MacRobot.java:78)
    at javafx.graphics/javafx.scene.robot.Robot.mouseMove(Robot.java:168)
    at com.example.testfx/com.example.testfx.HelloController.lambda$new$0(HelloController.java:32)
    at java.base/java.lang.Thread.run(Thread.java:833)

Code snippet:

import java.util.Random;

import javafx.fxml.FXML;
import javafx.scene.control.ToggleButton;
import javafx.scene.paint.Paint;
import javafx.scene.robot.Robot;
import javafx.scene.shape.Circle;
import lombok.SneakyThrows;

public class HelloController {

    private static final String red = "#da203f";
    private static final String green = "#2fb21e";
    public static final int FIVE_SECONDS = 5000;

    @FXML
    private Circle circle1;
    @FXML
    private ToggleButton toggleClick;
    public Thread t;
    
    public HelloController() {
        t = new Thread(() -> {

            while (true) {
                try {
                    Robot robot = new Robot();
                    Random random = new Random();
                    robot.mouseMove(random.nextInt(400), random.nextInt(400));
                    Thread.sleep(FIVE_SECONDS);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    @FXML
    @SneakyThrows
    protected void onToggleClicked() {
        if (toggleClick.isSelected()) {
            circle1.setFill(Paint.valueOf(red));
            t.interrupt();
        } else {
            circle1.setFill(Paint.valueOf(green));
            t.start();
        }
    }

If if put the while loop in onToggleClicked() method without new thread, mouse is moving but application freezes. I have tried also Platform.runLater but the effect is the same - app freezes.

keip
  • 1
  • 2
  • Post a [mre]. I assume you are using a `javafx.scene.robot.Robot`, since this is a JavaFX application? – James_D Dec 20 '22 at 15:02
  • yes, I've added imports to snippet – keip Dec 20 '22 at 15:05
  • please read the api doc of Robot, particularly the part about the exception that's thrown from mouseMoved (hint: it's the same that you are seeing .. ) You __must not__ try to change the ui from a background thread nor sleep the ui. Instead, use the animation api. – kleopatra Dec 20 '22 at 15:05
  • that's not an [mcve] - please read that help page to understand what's required and act accordingly – kleopatra Dec 20 '22 at 15:08
  • Use an animation for this kind of functionality. See [this answer](https://stackoverflow.com/a/60685975/2189127) in particular. – James_D Dec 20 '22 at 15:20
  • Animation worked, thanks for the tip. I couldn't find this answer before so I am putting here: https://stackoverflow.com/questions/9966136/javafx-periodic-background-task – keip Dec 20 '22 at 15:29

0 Answers0