Reputation: 3966
I am a bit confused about using Platform.runLater()
in javafx, as I got Platform.runLater()
will send the runnable paramater to thread queue, and execute it in sequential order in case it was called multiple time, as well as Platform.runLater()
is a single javafx thread
in my javafx application I am in-need to listen to mouse and keyboard events in all operating system not only inside javafx application
currently I am creating two Timeline
so I am doing something like the following:
class FirstTimeLineWrapperClass implements Runnable {
public void run() {
Timeline timeline1 = new Timeline(new KeyFrame(
Duration.seconds(1),
ae -> {
secondPassed++;
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
}
class SecondTimeLineWrapperClass implements Runnable {
public void run() {
Timeline timeline2 = new Timeline(new KeyFrame(
Duration.seconds(1),
ae -> {
secondPassed++;
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
}
And then I am calling:
Platform.runLater(new FirstTimeLineWrapperClass());
Platform.runLater(new SecondTimeLineWrapperClass());
The above is kinda clutter, but just to be clear about my question,
so is it let's say ok to do so, what might go wrong in the above code?
and if Platform.runLater()
will run in a single javafx thread, how the above code works concurrently?
As the docs mentions
Warning : A running Timeline is being referenced from the FX runtime. Infinite Timeline might result in a memory leak if not stopped properly. All the objects with animated properties would not be garbage collected.
Upvotes: 0
Views: 1616
Reputation: 209418
Animations don't create any additional threads, or run on any background threads.
You can think of the FX Application Thread as a loop that, in pseudocode, looks something like this (the actual details are considerably more complex):
while (applicationIsRunning()) {
if (anyEventsNeedHandling()) {
handleEvents();
}
processAnyRunnablesFromRunLaterQueue();
if (timeToUpdateScene()) {
if (animationsNeedProcessing()) {
processAnimations();
}
updateScene();
}
}
The way animations essentially work, is that a running animation registers itself somewhere that the main loop described above is aware of it. The animation can determine if it's time to do something - for example, in your Timeline
s the key frame executes every second, so it's relatively easy for the Timeline
to report if one or more key frames are due for processing, and the event handler will be invoked if necessary. The actual mechanics of this aren't specified, but that's the basic functionality.
Note that the play()
method just starts the animation (i.e. registers it for the FX Application Thread loop to check it) and exits immediately. So in your code where you start two Timeline
s on the FX Application thread in rapid succession, they will start immediately one after the other (effectively at almost the same time).
Consequently, you can start multiple animations, and they won't block the FX Application Thread. The usual rules apply for code being executed on the FX Application thread apply to code in any key frame handlers: it should not block and should not take a long time to run.
Also note that if you add runnables to the run-later queue faster than they can be executed, you will effectively block the FX Application Thread, giving the UI poor responsiveness (or blocking it entirely).
Upvotes: 3