I want to load up to nine panels in a TilePane. For each pane I have to first run a computation of the content (about 300ms) and then I have to build the Panel (about 500ms).
What I want is, that there are nine ProgressIndicators which exchanges with every panel after its computation.
I tried it with the Platform.runLater
command as well as with a service class. The result was always the same. The ProgressIndicator are shown, but not animated. After seconds there are all panels at once.
Is there a possibility, that the Indicators are animated the whole time and that I can exchange them one after another?
JavaFX provides a complete package to deal with the issues of multithreading and concurrency. There is an interface called Worker, an abstract class called Task, and ScheduledService for this purpose. The Task is basically a Worker implementation, ideal for implementing long running computation.
The JavaFX scene graph, which represents the graphical user interface of a JavaFX application, is not thread-safe and can only be accessed and modified from the UI thread also known as the JavaFX Application thread.
runLater. Run the specified Runnable on the JavaFX Application Thread at some unspecified time in the future. This method, which may be called from any thread, will post the Runnable to an event queue and then return immediately to the caller. The Runnables are executed in the order they are posted.
JavaFX uses a single-threaded rendering design, meaning only a single thread can render anything on the screen, and that is the JavaFX application thread. In fact, only the JavaFX application thread is allowed to make any changes to the JavaFX Scene Graph in general.
JavaFX has Event Dispatch Thread which it uses for UI events. All work with UI should happen on this thread. And non-UI calculations shouldn't happen there to avoid lags in UI.
See next code:
public class Indicators extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Pane root = new HBox();
stage.setScene(new Scene(root, 300, 100));
for (int i = 0; i < 10; i++) {
final ProgressIndicator pi = new ProgressIndicator(0);
root.getChildren().add(pi);
// separate non-FX thread
new Thread() {
// runnable for that thread
public void run() {
for (int i = 0; i < 20; i++) {
try {
// imitating work
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
final double progress = i*0.05;
// update ProgressIndicator on FX thread
Platform.runLater(new Runnable() {
public void run() {
pi.setProgress(progress);
}
});
}
}
}.start();
}
stage.show();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With