HEADS-UP: Threading restriction for Animation play, pause, stop now enforced USE CASE
Kevin Rushforth
kevin.rushforth at oracle.com
Wed Jan 24 13:15:31 UTC 2024
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 <javafx at 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 <nlisker at 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20240124/4f6657ab/attachment-0001.htm>
More information about the openjfx-dev
mailing list