<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    I also now favor option 2 and was in the process of writing
    something up recommending that we do that. Phil and I (and a couple
    others) had an offline discussion and think this is the way to go.<br>
    <br>
    Given the short amount of time to get this into 22, I will file the
    JBS issue in the next hour or so.<br>
    <br>
    Nir: if you want to take it, that would be great. Otherwise, I will
    do it. We need the PR and CSR filed before the end of this week.<br>
    <br>
    Regarding other methods that choose option 1, many of them are more
    complicated (e.g., scene mutation can be done on a background thread
    as long as the scene is not "showing") or must be synchronous.
    Animation starts something that conceptually happens later on the FX
    animation thread anyway, so wrapping it in a runLater (if not
    already on the right thread) doesn't really change the semantics in
    an appreciable way.<br>
    <br>
    -- Kevin<br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 1/24/2024 10:26 AM, Nir Lisker
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CA+0ynh8AunqnGeZO6CegupVREjSB5YuYMLhs08+BJ1wo_3wOvA@mail.gmail.com">
      
      <div dir="ltr">These are the options I see as reasonable:
        <div><br>
        </div>
        <div>1. Document that these methods *must* be run on the FX
          thread and throw an exception otherwise. This leaves it to the
          responsibility of the user. However, this will cause the
          backwards compatibility problems that Jugen brought up. As a
          side note, we do this in other methods already, but I always
          questioned why let the developer do something illegal - if
          there's only one execution path, force it.</div>
        <div>2. Document that these methods *are* run on the FX thread
          (the user doesn't need to do anything) and change the
          implementation to call runLater(...) internally unless they
          are already on the FX thread. This will be backwards
          compatible for the most part (see option 3). The downside
          might be some surprise when these methods behave differently.</div>
        <div>3. Document that it's *recommended* that these methods be
          run on the FX thread and let the user be responsible for the
          threading. We can explain that manipulating nodes that are
          attached to an active scenegraph should be avoided.</div>
        <div><br>
        </div>
        <div>I prefer option 2 over 1 regardless of the backwards
          compatibility issue even, but would like to know if I'm
          missing something here because in theory this change could be
          done to any "must run on the FX thread" method and I question
          why the user had the option to get an exception.</div>
        <div>Option 3 is risky and I wager a guess that it will be used
          wrongly more often than not. It does allow some (what I would
          call) valid niche uses. I never did it.</div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Wed, Jan 24, 2024 at
          4:21 PM Kevin Rushforth <<a href="mailto:kevin.rushforth@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">kevin.rushforth@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div> <font face="Helvetica, Arial, sans-serif">I'd like to
              hear from the others on this. I don't see any fundamental
              problem with having the play/pause/stop methods wrap their
              implementation in a runLater (if not on the FX Application
              thread already), and documenting that it does so, if we
              can get general agreement.<br>
              <br>
              -- Kevin<br>
              <br>
              <br>
            </font>
            <div>On 1/24/2024 5:29 AM, Jurgen Doll wrote:<br>
            </div>
            <blockquote type="cite">
              <div><big>Hi Kevin</big></div>
              <div><big><br>
                </big></div>
              <div><big>If I may make one more final appeal then to an
                  alternative solution please.</big></div>
              <div><big><br>
                </big></div>
              <div><big>Could we then instead of throwing an Exception
                  rather invoke runLater if needed inside play, stop,
                  and resume.</big></div>
              <div><big><br>
                </big></div>
              <div><big>Putting the onus on the developer is fine if it
                  is the developer that is invoking the call, but if
                  it's in a library then it's a no go.</big><big><br>
                </big><big><br>
                </big><big>In my application I have two libraries that I
                  know of where this happens. The major problem is that
                  with FX22 as it now stands my </big><big>application
                  just crashes because play() does an FX thread check
                  and throws an Exception which it never did before.
                  There are bound </big><big>to be other applications
                  out there that are going to find themselves in a
                  similar position.</big></div>
              <div><big><br>
                </big></div>
              <div><big>PLEASE !</big></div>
              <div><big><br>
                </big></div>
              <div><big>Regards</big></div>
              <div><big>Jurgen</big></div>
              <div><big><br>
                </big></div>
              <div><br>
              </div>
              <div><br>
              </div>
              <div>On Wed, 24 Jan 2024 15:15:31 +0200, Kevin Rushforth <a href="mailto:kevin.rushforth@oracle.com" target="_blank" moz-do-not-send="true"><kevin.rushforth@oracle.com></a>
                wrote:<br>
              </div>
              <br>
              <blockquote style="margin:0px 0px 0.8ex;border-left:2px solid rgb(0,0,255);padding-left:1ex">
                Thank you to Jurgen for raising the question and to Nir,
                John, and Michael for evaluating it.<br>
                <br>
                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.<br>
                <br>
                We will proceed with the current approach and let
                JDK-8159048 stand. Further, we will proceed with <a href="https://bugs.openjdk.org/browse/JDK-8324219" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8324219</a>
                which is under review in <a href="https://urldefense.com/v3/__https://github.com/openjdk/jfx/pull/1342__;!!ACWV5N9M2RV99hQ!PLtaZAvaobOk-fe_DRSy2AHiPOFUaK683TVXWIvmjnTiUGhmBp3x_GIy_wlMuEV3IHTUMx37HxJHiVuWiFRR$" target="_blank" moz-do-not-send="true">https://github.com/openjdk/jfx/pull/1342</a><br>
                <br>
                -- Kevin<br>
                <br>
                <div>On 1/24/2024 12:30 AM, Nir Lisker wrote:<br>
                </div>
                <blockquote type="cite">
                  <div dir="auto">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. 
                    <div dir="auto"><br>
                    </div>
                    <div dir="auto">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.</div>
                    <div dir="auto"><br>
                    </div>
                    <div dir="auto">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. </div>
                    <div dir="auto"><br>
                    </div>
                    <div dir="auto">- Nir</div>
                  </div>
                  <br>
                  <div class="gmail_quote">
                    <div dir="ltr" class="gmail_attr">On Mon, Jan 22,
                      2024, 12:59 Jurgen Doll <<a href="mailto:javafx@ivoryemr.co.za" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">javafx@ivoryemr.co.za</a>>
                      wrote:<br>
                    </div>
                    <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                      <div>
                        <div><big>Here's an example as requested by Nir:</big></div>
                        <div><big><br>
                          </big></div>
                        <div><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)"> FxTimeLineTest </span><span style="color:rgb(127,0,85);font-weight:bold">extends</span><span style="color:rgb(0,0,0)"> Application</span></div>
                        <div>
                          <div style="background-color:rgb(255,255,255);padding:0px 2px">
                            <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px"><span style="color:rgb(0,0,0)">{</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> BorderPane </span><span style="color:rgb(0,0,192)">bp</span><span style="color:rgb(0,0,0)"> = </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> BorderPane( </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> Label(</span><span style="color:rgb(42,0,255)">"Loading"</span><span style="color:rgb(0,0,0)">) );</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">void</span><span style="color:rgb(0,0,0)"> main( String[] </span><span style="color:rgb(106,62,62)">args</span><span style="color:rgb(0,0,0)"> ) {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(0,0,0);font-style:italic">launch</span><span style="color:rgb(0,0,0)">( FxTimeLineTest.</span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(106,62,62)">args</span><span style="color:rgb(0,0,0)"> );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    }</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(100,100,100)">@Override</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">void</span><span style="color:rgb(0,0,0)"> start( Stage </span><span style="color:rgb(106,62,62)">primaryStage</span><span style="color:rgb(0,0,0)"> ) </span><span style="color:rgb(127,0,85);font-weight:bold">throws</span><span style="color:rgb(0,0,0)"> Exception {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> Thread( </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> LoadScene() ).start();</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(106,62,62)">primaryStage</span><span style="color:rgb(0,0,0)">.setScene( </span>
 <span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> Scene( </span><span style="color:rgb(0,0,192)">bp</span><span style="color:rgb(0,0,0)">, 300, 200 ) );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(106,62,62)">primaryStage</span><span style="color:rgb(0,0,0)">.setTitle( </span><span style="color:rgb(42,0,255)">"Memory Usage"</span><span style="color:rgb(0,0,0)"> );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(106,62,62)">primaryStage</span><span style="color:rgb(0,0,0)">.show();</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    }</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)"> LoadScene </span><span style="color:rgb(127,0,85);font-weight:bold">extends</span><span style="color:rgb(0,0,0)"> Task<Parent> {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(100,100,100)">@Override</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">protected</span><span style="color:rgb(0,0,0)"> Parent call() </span><span style="color:rgb(127,0,85);font-weight:bold">throws</span><span style="color:rgb(0,0,0)"> Exception {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            Parent </span><span style="color:rgb(106,62,62)">p</span><span style="color:rgb(0,0,0)"> = FXMLLoader.</span><span style="color:rgb(0,0,0);font-style:italic">load</span><span style="color:rgb(0,0,0)">( getClass(
 ).getResource(</span><span style="color:rgb(42,0,255)">"TestView.fxml"</span><span style="color:rgb(0,0,0)">) );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            Thread.</span><span style="color:rgb(0,0,0);font-style:italic">sleep</span><span style="color:rgb(0,0,0)">( 1000 );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            </span><span style="color:rgb(127,0,85);font-weight:bold">return</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(106,62,62)">p</span><span style="color:rgb(0,0,0)">;</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        }</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(100,100,100)">@</span><span style="color:rgb(100,100,100)">Override</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">protected</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">void</span><span style="color:rgb(0,0,0)"> succeeded() {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            </span><span style="color:rgb(0,0,192)">bp</span><span style="color:rgb(0,0,0)">.setCenter( getValue() );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        }</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(100,100,100)">@</span><span style="color:rgb(100,100,100)">Override</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">protected</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">void</span><span style="color:rgb(0,0,0)"> failed() {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            getException().printStackTrace();</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">}

</span></p></div>
                          </div>
                        </div>
                        <div>
                          <div style="background-color:rgb(255,255,255);padding:0px 2px">
                            <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px">------------------------------------------------------------------------------------------------------</p></div>
                          </div>
                        </div>
                        <div><br>
                        </div>
                        <div>
                          <div style="background-color:rgb(255,255,255);padding:0px 2px">
                            <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px"><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">class</span><span style="color:rgb(0,0,0)"> TestView</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">{</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(100,100,100)">@</span><span style="color:rgb(100,100,100)">FXML</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> Label </span><span style="color:rgb(0,0,192)">memory</span><span style="color:rgb(0,0,0)">;</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">double</span><span style="color:rgb(0,0,0)">  </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">MEGABYTE</span><span style="color:rgb(0,0,0)"> = 1024 * 1024;</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">    </span><span style="color:rgb(100,100,100)">@</span><span style="color:rgb(100,100,100)">FXML</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(127,0,85);font-weight:bold">void</span><span style="color:rgb(0,0,0)"> initialize()</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(127,0,85);font-weight:bold">var</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(106,62,62)">updater</span><span style="color:rgb(0,0,0)"> = </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> Timeline</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        (</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> K
 eyFrame( Duration.</span><span style="color:rgb(0,0,0);font-style:italic">seconds</span><span style="color:rgb(0,0,0)">(2.5), </span><span style="color:rgb(106,62,62)">event</span><span style="color:rgb(0,0,0)"> -></span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            {</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">                </span><span style="color:rgb(127,0,85);font-weight:bold">var</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(106,62,62)">runtime</span><span style="color:rgb(0,0,0)"> = Runtime.</span><span style="color:rgb(0,0,0);font-style:italic">getRuntime</span><span style="color:rgb(0,0,0)">();</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">                </span><span style="color:rgb(127,0,85);font-weight:bold">double</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(106,62,62)">maxMemory</span><span style="color:rgb(0,0,0)"> = </span><span style="color:rgb(106,62,62)">runtime</span><span style="color:rgb(0,0,0)">.maxMemory() / </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">MEGABYTE</span><span style="color:rgb(0,0,0)">;</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">                </span><span style="color:rgb(127,0,85);font-weight:bold">double</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(106,62,62)">usedMemory</span><span style="color:rgb(0,0,0)"> = (</span><span style="color:rgb(106,62,62)">runtime</span><span style="color:rgb(0,0,0)">.totalMemory() - </span><span style="color:rgb(106,62,62)">runtime</span><span style="color:rgb(0,0,0)">.freeMemory()) / </span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">MEGABYTE</span><span style="color:rgb(0,0,0)">;</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">                </span><span style="color:rgb(0,0,192)">memory</span><span style="color:rgb(0,0,0)">.setText( (</span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)">) </span><span style="color:rgb(106,62,62)">usedMemory</span><span style="color:rgb(0,0,0)"> + </span><span>" MB / "</span><span style="color:rgb(0,0,0)"> + (</span><span style="color:rgb(127,0,85);font-weight:bold">int</span><span style="color:rgb(0,0,0)">) </span><span style="color:rgb(106,62,62)">maxMemory</span><span style="color:rgb(0,0,0)"> +</span><span style="color:rgb(42,0,255)">" MB"</span><span style="color:rgb(0,0,0)"> );</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">            })</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        );</span></p><p style="margin:0px">
</p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(106,62,62)">updater</span><span style="color:rgb(0,0,0)">.setCycleCount(Animation.</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">INDEFINITE</span><span style="color:rgb(0,0,0)">);
        // This FXML is being loaded on a background thread
</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">        </span><span style="color:rgb(106,62,62)">updater</span><span style="color:rgb(0,0,0)">.play();</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">    }</span></p><p style="margin:0px"><span style="color:rgb(0,0,0)">}

</span></p></div>
                          </div>
                        </div>
                        <div>
                          <div style="background-color:rgb(255,255,255);padding:0px 2px">
                            <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px">------------------------------------------------------------------------------------------------------</p></div>
                          </div>
                        </div>
                        <div><br>
                        </div>
                        <div> <span style="color:rgb(0,0,0)"><big>TestView.fxml</big></span>
                        </div>
                        <div><br>
                        </div>
                        <div>
                          <div style="background-color:rgb(255,255,255);padding:0px 2px">
                            <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><div style="background-color:rgb(255,255,255);padding:0px 2px"><div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:Consolas;font-size:10pt;white-space:pre-wrap"><p style="margin:0px"><?xml version="1.0" encoding="UTF-8"?></p><p style="margin:0px">
</p><p style="margin:0px"><?import javafx.scene.control.Label?></p><p style="margin:0px"><?import javafx.scene.layout.StackPane?></p><p style="margin:0px">
</p><p style="margin:0px"><StackPane xmlns:fx="<a href="https://urldefense.com/v3/__http://javafx.com/fxml/1__;!!ACWV5N9M2RV99hQ!PLtaZAvaobOk-fe_DRSy2AHiPOFUaK683TVXWIvmjnTiUGhmBp3x_GIy_wlMuEV3IHTUMx37HxJHia1cBAoi$" rel="noreferrer" target="_blank" moz-do-not-send="true">http://javafx.com/fxml/1</a>" fx:controller="TestView"></p><p style="margin:0px">   <children></p><p style="margin:0px">      <Label fx:id="memory" text="Current / Max MB" ></p><p style="margin:0px">         <properties hashCode="12345" /></p><p style="margin:0px">      </Label></p><p style="margin:0px">   </children></p><p style="margin:0px"></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 href="mailto:nlisker@gmail.com" rel="noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">nlisker@gmail.com</a>>
                          wrote:<br>
                        </div>
                        <br>
                        <blockquote style="margin:0px 0px 0.8ex;border-left:2px solid rgb(0,0,255);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>
                      </div>
                    </blockquote>
                  </div>
                </blockquote>
                <br>
              </blockquote>
              <br>
              <br>
              <br>
              <div id="m_-3605241258564149313m_2670470793887508609M2Signature">
                <div>-- </div>
                <div>Using Opera's mail client: <a href="https://urldefense.com/v3/__http://www.opera.com/mail/__;!!ACWV5N9M2RV99hQ!PLtaZAvaobOk-fe_DRSy2AHiPOFUaK683TVXWIvmjnTiUGhmBp3x_GIy_wlMuEV3IHTUMx37HxJHifb0G69Z$" target="_blank" moz-do-not-send="true">http://www.opera.com/mail/</a></div>
              </div>
            </blockquote>
            <br>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
  </body>
</html>