<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>This seems like a reasonable use case, and perhaps this was the
      original intent of the "asynchronous call" documentation.</p>
    <p>The problem though is that the play/stop code does not seem to
      take into account being called from a different thread (there are
      several synchronization issues when I delved into that code).</p>
    <p>So then there's a choice to make I think, either:</p>
    <p>- Disallow it completely, and have users wrap it into
      Platform.runLater()<br>
      - Have play/stop do the wrapping itself<br>
      - Make the methods thread safe by fixing the synchronization
      issues</p>
    <p>--John<br>
    </p>
    <div class="moz-cite-prefix">On 22/01/2024 11:59, Jurgen Doll wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:op.2hx3gmz30ae2rt@admin-pc">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <style type="text/css">body { font-family:'Calibri'; font-size:13px}</style>
      <div><big>Here's an example as requested by Nir:</big></div>
      <div><big><br>
        </big></div>
      <div><span style="color:#7f0055;font-weight:bold;">public</span><span
          style="color:#000000;"> </span><span
          style="color:#7f0055;font-weight:bold;">class</span><span
          style="color:#000000;"> FxTimeLineTest </span><span
          style="color:#7f0055;font-weight:bold;">extends</span><span
          style="color:#000000;"> Application</span></div>
      <div>
        <div style="background-color:#ffffff;padding:0px 2px 0px 2px;">
          <div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:10pt;white-space:pre;"><p style="margin:0;"><span style="color:#000000;">{</span></p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#7f0055;font-weight:bold;">private</span><span style="color:#000000;"> BorderPane </span><span style="color:#0000c0;">bp</span><span style="color:#000000;"> = </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> BorderPane( </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> Label(</span><span style="color:#2a00ff;">"Loading"</span><span style="color:#000000;">) );</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#7f0055;font-weight:bold;">public</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">static</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">void</span><span style="color:#000000;"> main( String[] </span><span style="color:#6a3e3e;">args</span><span style="color:#000000;"> ) {</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#000000;font-style:italic;">launch</span><span style="color:#000000;">( FxTimeLineTest.</span><span style="color:#7f0055;font-weight:bold;">class</span><span style="color:#000000;">, </span><span style="color:#6a3e3e;">args</span><span style="color:#000000;"> );</span></p><p style="margin:0;"><span style="color:#000000;">    }</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#646464;">@Override</span></p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#7f0055;font-weight:bold;">public</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">void</span><span style="color:#000000;"> start( Stage </span><span style="color:#6a3e3e;">primaryStage</span><span style="color:#000000;"> ) </span><span style="color:#7f0055;font-weight:bold;">throws</span><span style="color:#000000;"> Exception {</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> Thread( </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> LoadScene() ).start();</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#6a3e3e;">primaryStage</span><span style="color:#000000;">.setScene( </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> Scene( </span><span style="color:#0000c0;">bp</span><span style="color:#000000;">, 300, 200 ) );</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#6a3e3e;">primaryStage</span><span style="color:#000000;">.setTitle( </span><span style="color:#2a00ff;">"Memory Usage"</span><span style="color:#000000;"> );</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#6a3e3e;">primaryStage</span><span style="color:#000000;">.show();</span></p><p style="margin:0;"><span style="color:#000000;">    }</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#7f0055;font-weight:bold;">private</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">class</span><span style="color:#000000;"> LoadScene </span><span style="color:#7f0055;font-weight:bold;">extends</span><span style="color:#000000;"> Task<Parent> {</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#646464;">@Override</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">protected</span><span style="color:#000000;"> Parent call() </span><span style="color:#7f0055;font-weight:bold;">throws</span><span style="color:#000000;"> Exception {</span></p><p style="margin:0;"><span style="color:#000000;">            Parent </span><span style="color:#6a3e3e;">p</span><span style="color:#000000;"> = FXMLLoader.</span><span style="color:#000000;font-style:italic;">load</span><span style="color:#000000;">( getClass().getResource(</span><span style="color:#2a00ff;">"TestView.fxml"</span><span style="color:#000000;">) );</span></p><p style="margin:0;"><span style="color:#000000;">            Thread.</span><span style="color:#000000;font-style:italic;">sleep</span><span style="color:#000000;">( 1000 );</span></p><p style="margin:0;"><span style="color:#000000;">            </span><span style="color:#7f0055;font-weight:bold;">return</span><span style="color:#000000;"> </span><span style="color:#6a3e3e;">p</span><span style="color:#000000;">;</span></p><p style="margin:0;"><span style="color:#000000;">        }</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#646464;">@</span><span style="color:#646464;">Override</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">protected</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">void</span><span style="color:#000000;"> succeeded() {</span></p><p style="margin:0;"><span style="color:#000000;">            </span><span style="color:#0000c0;">bp</span><span style="color:#000000;">.setCenter( getValue() );</span></p><p style="margin:0;"><span style="color:#000000;">        }</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#646464;">@</span><span style="color:#646464;">Override</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">protected</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">void</span><span style="color:#000000;"> failed() {</span></p><p style="margin:0;"><span style="color:#000000;">            getException().printStackTrace();</span></p><p style="margin:0;"><span style="color:#000000;">        }</span></p><p style="margin:0;"><span style="color:#000000;">    }</span></p><p style="margin:0;"><span style="color:#000000;">}

</span></p></div>
        </div>
      </div>
      <div>
        <div style="background-color:#ffffff;padding:0px 2px 0px 2px;">
          <div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:10pt;white-space:pre;"><p style="margin:0;">------------------------------------------------------------------------------------------------------</p></div>
        </div>
      </div>
      <div><br>
      </div>
      <div>
        <div style="background-color:#ffffff;padding:0px 2px 0px 2px;">
          <div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:10pt;white-space:pre;"><p style="margin:0;"><span style="color:#7f0055;font-weight:bold;">public</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">class</span><span style="color:#000000;"> TestView</span></p><p style="margin:0;"><span style="color:#000000;">{</span></p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#646464;">@</span><span style="color:#646464;">FXML</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">private</span><span style="color:#000000;"> Label </span><span style="color:#0000c0;">memory</span><span style="color:#000000;">;</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#7f0055;font-weight:bold;">private</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">static</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">final</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">double</span><span style="color:#000000;">  </span><span style="color:#0000c0;font-style:italic;font-weight:bold;">MEGABYTE</span><span style="color:#000000;"> = 1024 * 1024;</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">    </span><span style="color:#646464;">@</span><span style="color:#646464;">FXML</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">private</span><span style="color:#000000;"> </span><span style="color:#7f0055;font-weight:bold;">void</span><span style="color:#000000;"> initialize()</span></p><p style="margin:0;"><span style="color:#000000;">    {</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#7f0055;font-weight:bold;">var</span><span style="color:#000000;"> </span><span style="color:#6a3e3e;">updater</span><span style="color:#000000;"> = </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> Timeline</span></p><p style="margin:0;"><span style="color:#000000;">        (</span></p><p style="margin:0;"><span style="color:#000000;">            </span><span style="color:#7f0055;font-weight:bold;">new</span><span style="color:#000000;"> KeyFrame( Duration.</span><span style="color:#000000;font-style:italic;">seconds</span><span style="color:#000000;">(2.5), </span><span style="color:#6a3e3e;">event</span><span style="color:#000000;"> -></span></p><p style="margin:0;"><span style="color:#000000;">            {</span></p><p style="margin:0;"><span style="color:#000000;">                </span><span style="color:#7f0055;font-weight:bold;">var</span><span style="color:#000000;"> </span><span style="color:#6a3e3e;">runtime</span><span style="color:#000000;"> = Runtime.</span><span style="color:#000000;font-style:italic;">getRuntime</span><span style="color:#000000;">();</span></p><p style="margin:0;"><span style="color:#000000;">                </span><span style="color:#7f0055;font-weight:bold;">double</span><span style="color:#000000;"> </span><span style="color:#6a3e3e;">maxMemory</span><span style="color:#000000;"> = </span><span style="color:#6a3e3e;">runtime</span><span style="color:#000000;">.maxMemory() / </span><span style="color:#0000c0;font-style:italic;font-weight:bold;">MEGABYTE</span><span style="color:#000000;">;</span></p><p style="margin:0;"><span style="color:#000000;">                </span><span style="color:#7f0055;font-weight:bold;">double</span><span style="color:#000000;"> </span><span style="color:#6a3e3e;">usedMemory</span><span style="color:#000000;"> = (</span><span style="color:#6a3e3e;">runtime</span><span style="color:#000000;">.totalMemory() - </span><span style="color:#6a3e3e;">runtime</span><span style="color:#000000;">.freeMemory()) / </span><span style="color:#0000c0;font-style:italic;font-weight:bold;">MEGABYTE</span><span style="color:#000000;">;</span></p><p style="margin:0;"><span style="color:#000000;">                </span><span style="color:#0000c0;">memory</span><span style="color:#000000;">.setText( (</span><span style="color:#7f0055;font-weight:bold;">int</span><span style="color:#000000;">) </span><span style="color:#6a3e3e;">usedMemory</span><span style="color:#000000;"> + </span><span style="color:#2a00ff;">" MB / "</span><span style="color:#000000;"> + (</span><span style="color:#7f0055;font-weight:bold;">int</span><span style="color:#000000;">) </span><span style="color:#6a3e3e;">maxMemory</span><span style="color:#000000;"> +</span><span style="color:#2a00ff;">" MB"</span><span style="color:#000000;"> );</span></p><p style="margin:0;"><span style="color:#000000;">            })</span></p><p style="margin:0;"><span style="color:#000000;">        );</span></p><p style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#6a3e3e;">updater</span><span style="color:#000000;">.setCycleCount(Animation.</span><span style="color:#0000c0;font-style:italic;font-weight:bold;">INDEFINITE</span><span style="color:#000000;">);
        // This FXML is being loaded on a background thread
</span></p><p style="margin:0;"><span style="color:#000000;">        </span><span style="color:#6a3e3e;">updater</span><span style="color:#000000;">.play();</span></p><p style="margin:0;"><span style="color:#000000;">    }</span></p><p style="margin:0;"><span style="color:#000000;">}

</span></p></div>
        </div>
      </div>
      <div>
        <div style="background-color:#ffffff;padding:0px 2px 0px 2px;">
          <div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:10pt;white-space:pre;"><p style="margin:0;">------------------------------------------------------------------------------------------------------</p></div>
        </div>
      </div>
      <div><br>
      </div>
      <div>
        <span style="color:#000000;"><big>TestView.fxml</big></span>
      </div>
      <div><br>
      </div>
      <div>
        <div style="background-color:#ffffff;padding:0px 2px 0px 2px;">
          <div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:10pt;white-space:pre;"><div style="background-color:#ffffff;padding:0px 2px 0px 2px;"><div style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:10pt;white-space:pre;"><p style="margin:0;"><?xml version="1.0" encoding="UTF-8"?></p><p style="margin:0;">
</p><p style="margin:0;"><?import javafx.scene.control.Label?></p><p style="margin:0;"><?import javafx.scene.layout.StackPane?></p><p style="margin:0;">
</p><p style="margin:0;"><StackPane xmlns:fx=<a class="moz-txt-link-rfc2396E" href="http://javafx.com/fxml/1">"http://javafx.com/fxml/1"</a> fx:controller="TestView"></p><p style="margin:0;">   <children></p><p style="margin:0;">      <Label fx:id="memory" text="Current / Max MB" ></p><p style="margin:0;">         <properties hashCode="12345" /></p><p style="margin:0;">      </Label></p><p style="margin:0;">   </children></p><p style="margin:0;"></StackPane></p></div></div></div>
        </div>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>On Sat, 20 Jan 2024 17:08:41 +0200, Nir Lisker
        <a class="moz-txt-link-rfc2396E" href="mailto:nlisker@gmail.com"><nlisker@gmail.com></a> wrote:<br>
      </div>
      <br>
      <blockquote style="margin: 0 0 0.80ex; border-left: #0000FF 2px
        solid; padding-left: 1ex">
        <div dir="ltr">Hi Jurgen,
          <div><br>
          </div>
          <div>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?</div>
          <div><br>
          </div>
          <div>- Nir</div>
        </div>
      </blockquote>
    </blockquote>
  </body>
</html>