Long-running operations must not be run on the JavaFX application thread, since this prevents JavaFX from updating the UI, resulting in a frozen UI.
Furthermore any change to a Node
that is part of a "live" scene graph must happen on the JavaFX application thread. Platform.runLater
can be used to execute those updates on the JavaFX application thread.
The following example demonstrates how to update a Text
Node
repeatedly from a different thread:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class CounterApp extends Application {
private int count = 0;
private final Text text = new Text(Integer.toString(count));
private void incrementCount() {
count++;
text.setText(Integer.toString(count));
}
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.getChildren().add(text);
Scene scene = new Scene(root, 200, 200);
// longrunning operation runs on different thread
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Runnable updater = new Runnable() {
@Override
public void run() {
incrementCount();
}
};
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
// UI update is run on the Application thread
Platform.runLater(updater);
}
}
});
// don't let thread prevent JVM shutdown
thread.setDaemon(true);
thread.start();
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}