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

Reply via email to