Thank you to Jurgen for raising the question and to Nir, John, and
Michael for evaluating it.
I conclude that there is insufficient motivation to revert the change in
behavior implemented by JDK-8159048 to allow calling the play/pause/stop
methods of Animation on a background thread. Doing so without making it
fully multi-thread-safe would be asking for problems, and making it
fully multi-thread-safe would be a fair bit of work to do it right
without a clear benefit.
We will proceed with the current approach and let JDK-8159048 stand.
Further, we will proceed with
https://bugs.openjdk.org/browse/JDK-8324219 which is under review in
https://github.com/openjdk/jfx/pull/1342
-- Kevin
On 1/24/2024 12:30 AM, Nir Lisker wrote:
After playing around with the code sample, I think that this is not
the right way to use the animation. The reason is that there is no
point in starting the animation before the control is attached to the
scenegraph, or even made visible. A small refactoring where, e.g., the
controller class exposes a method to start the animation in
onSucceeded or just calls it on the FX thread is enough. I never start
an animation as part of the construction because it's not the right
time. John suggested tying the lifecycle of the animation to the
showing of the node, which also solves the problem.
There are animations like PauseTransition or other non-interfering
Timelines that could reasonably be run on a background thread. Or
maybe just on an unconnected control. This could be a reason to not
limit animation methods to the FX thread at the expense of possible
user errors, but document the pitfall.
I don't see a good use case for modifying controls in a background
thread while still interacting with the scenegraph, hence for adding
multithread support.
- Nir
On Mon, Jan 22, 2024, 12:59 Jurgen Doll <jav...@ivoryemr.co.za> wrote:
Here's an example as requested by Nir:
publicclassFxTimeLineTest extendsApplication
{
privateBorderPane bp= newBorderPane( newLabel("Loading") );
publicstaticvoidmain( String[] args) {
launch( FxTimeLineTest.class, args);
}
@Override
publicvoidstart( Stage primaryStage) throwsException {
newThread( newLoadScene() ).start();
primaryStage.setScene( newScene( bp, 300, 200 ) );
primaryStage.setTitle( "Memory Usage");
primaryStage.show();
}
privateclassLoadScene extendsTask<Parent> {
@OverrideprotectedParent call() throwsException {
Parent p= FXMLLoader.load( getClass().getResource("TestView.fxml") );
Thread.sleep( 1000 );
returnp;
}
@Overrideprotectedvoidsucceeded() {
bp.setCenter( getValue() );
}
@Overrideprotectedvoidfailed() {
getException().printStackTrace();
}
}
}
------------------------------------------------------------------------------------------------------
publicclassTestView
{
@FXMLprivateLabel memory;
privatestaticfinaldoubleMEGABYTE= 1024 * 1024;
@FXMLprivatevoidinitialize()
{
varupdater= newTimeline
(
newKeyFrame( Duration.seconds(2.5), event->
{
varruntime= Runtime.getRuntime();
doublemaxMemory= runtime.maxMemory() / MEGABYTE;
doubleusedMemory= (runtime.totalMemory() - runtime.freeMemory()) /
MEGABYTE;
memory.setText( (int) usedMemory+ " MB / "+ (int) maxMemory+" MB");
})
);
updater.setCycleCount(Animation.INDEFINITE); // This FXML is being
loaded on a background thread
updater.play();
}
}
------------------------------------------------------------------------------------------------------
TestView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<StackPane xmlns:fx="http://javafx.com/fxml/1"
fx:controller="TestView">
<children>
<Label fx:id="memory" text="Current / Max MB" >
<properties hashCode="12345" />
</Label>
</children>
</StackPane>
On Sat, 20 Jan 2024 17:08:41 +0200, Nir Lisker <nlis...@gmail.com>
wrote:
Hi Jurgen,
What I'm confused about the most is what it is you are
actually trying to do that necessitates the use of animations
outside of the FX thread. You said that you need to initialize
controls on another thread, and that you are using Task (both
of which are fine), but how does playing animations relate?
Playing an animation is something that is done explicitly,
usually in order to manipulate data. Can you give a real use
case, like a minimized version of what you're doing?
- Nir