Javafx et du Soleil.robot en verre causant des problèmes IllegalStateException en raison de l'utilisation de Threads


J'écris un contrôleur JavaFX qui déplace la souris une fois toutes les 5 secondes. Ce contrôleur fait également un autre travail en même temps tout en faisant cela. Par conséquent, j'ai utilisé des threads séparés pour chacune de ces tâches. Voici mon code:

Thread dynamicMouseThread = new Thread(new Runnable() {
    @Override
    public void run() {
        boolean isRunning = true;
        long timeout = 5000;
        int x = 5;
        Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
        while (isRunning) {
            try {
                Thread.sleep(timeout);
            } catch (InterruptedException ex) {
                isRunning = false;
            }
            x = x == 5 ? x + 5 : 5;
            robot.mouseMove(x, 5);  // This line causes the error.
        }
    }
});


@Override
public void initialize(URL url, ResourceBundle rb) {
    dynamicTimerThread.setName("Dynamic Timer Thread");
    dynamicMouseThread.setName("Dynamic Mouse Thread");
    dynamicTimerThread.start();
    dynamicMouseThread.start();
}

C'est l'erreur que je semble obtenir. Merci de m'aider. ce que je fais mal?

Exception in thread "Dynamic Mouse Thread" java.lang.IllegalStateException: This operation is permitted on the event thread only; currentThread = Dynamic Mouse Thread
at com.sun.glass.ui.Application.checkEventThread(Application.java:427)
at com.sun.glass.ui.Robot.<init>(Robot.java:52)
at com.sun.glass.ui.win.WinRobot.<init>(WinRobot.java:33)
at com.sun.glass.ui.win.WinApplication.createRobot(WinApplication.java:205)
at main.SubDocumentController$1.run(SubDocumentController.java:56)
at java.lang.Thread.run(Thread.java:745)
Author: Rico2988, 2014-06-29

1 answers

L'erreur que vous obtenez est légèrement trompeuse, elle devrait vraiment faire référence au Fil d'application JavaFX, c'est là que tout accès aux objets JavaFX doit se produire.

Dans JavaFX, vous ne devriez pas créer de threads comme celui-ci. Il existe des classes de concurrence pour cela dans le package javafx.concurrent, telles que Task et Worker qui enveloppent essentiellement un Runnable pour vous. Utilisation Platform#runLater(Runnable) pour exécuter ces dans le bon contexte.

Donc, votre le code devrait ressembler à ceci:

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        // ...
        Robot robot = com.sun.glass.ui.Application.GetApplication().createRobot();
        // ...
        robot.mouseMove(x, 5);
    }
});
 2
Author: grkvlt, 2014-06-28 23:13:44