I have a single scene JavaFX app, that runs an animation, the animation needs to switch back and forth between two states.
Based on an example in "Java How to Program, 11/e, Early Objects"
I have written a controller that creates a similar setup in the initialization method,
And a task with boolean value that signals the animation timer when to switch states by fliping its value and then sleep.
I keep getting "java.lang.IllegalStateException: Task must only be used from the FX Application Thread" thrown from the call()
method no metter what I do.
here is a simplified version of the controller:
public class AnimationController {
@FXML public AnimationTimer myAnimationTimerExtention;
private ExecutorService executorService;
public void initialize() {
myAnimationTimerExtention.setState(false);
TimeingTask task = new TimeingTask (Duration.ofSeconds(5));
task .valueProperty().addListener((observableValue, oldValue, newValue) -> {
myAnimationTimerExtention.setState(false);
});
executorService = Executors.newFixedThreadPool(1);
executorService.execute(timeTrafficLightTask);
executorService.shutdown();
}
And here is my task:
public class TimeingTask extends Task<Boolean> {
private final Duration duration;
public TimeingTask(Duration duration) {
this.duration = duration;
updateValue(true);
}
@Override
protected Boolean call() throws Exception {
while (!isCancelled()) {
updateValue(!getValue());
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
updateMessage("timing task got interrupted");
}
}
return true;
}
}
I have tried so far:
- moveing the initialization to be done in a button's action
- removing the listener and the update of the value
- verifing with
Thread.currentThread().getName()
I'm on the application theard in the controller. - chack if the task somehow get canceld to see if the issue relates to this javafx bug, it is not getting canceld.
- compiling and running the example I'm basing this on to see if this is realted to my IDE configuration or JDK version, the example worked.
- surrounding the
updateValue()
in aPlatform.runLater()
the excption is thrown on theTheard.sleep()
in all of the above scenarios the excption was thrown