0

The way my program works, I have a method being called when the button is pressed. Then, the idea is that I have a new thread that has a while loop that calls another method every specified amount of time until the togglebutton is pressed again. How would I program such a thing? I tried Thread.wait() but it causes issues with the GUI updating.

Solved. Thank you!

sfcor
  • 9
  • 2
  • 1
    If your periodic task is simple and quick then use the [animation API](https://openjfx.io/javadoc/13/javafx.graphics/javafx/animation/package-summary.html) (e.g. [JavaFX periodic background task](https://stackoverflow.com/questions/9966136/javafx-periodic-background-task)). Otherwise, if it's a periodic _background_ task, see [`ScheduledService`](https://openjfx.io/javadoc/13/javafx.graphics/javafx/concurrent/ScheduledService.html). – Slaw Nov 19 '19 at 09:45

1 Answers1

1

You could try to save the Thread object to a global variable and stop it when the toggleButton is pressed again.

Using the wait method on the thread will not work, because wait does not work like you expect it (see Object.wait() in javadoc)

The second problem (IllegalStateException: Not on FX application thread) is probably caused by the method performAction(ActionEvent) because it tries to change things in the GUI, which is not allowed from another thread than the application thread. To avoid this you can use Platform.runLater(Runnable) (see javadock or this post)

A solution could look like this:

private Thread thread;

//call this method every time the toggle button is pressed
private void play(final ActionEvent ae) {
    if (thread == null) {
        //start in a new thread
        thread = new Thread(new Runnable() {//better add a runnable to the new Thread than overwriting the run method of Thread
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {//run until the thread is interrupted
                    try {
                        Thread.sleep(speed);
                        //run this in platform to avoid the IllegalStateException that no fx thread is used
                        Plaform.runLater(() -> performAction(ae));
                    }
                    catch (InterruptedException e) {
                        //e.printStackTrace();
                        //set the interrupted flag again (was unset when exception was caught)
                        Thread.currentThread().interrupt();
                    }
                }
            }
        });
        thread.start();
    }
    else {
        //stop the current thread
        thread.interrupt();
        thread = null;
    }
}
Tobias
  • 2,547
  • 3
  • 14
  • 29