<!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>