Use ScenePulseListener to avoid expensive recalculations?

Martin Sladecek martin.sladecek at oracle.com
Thu Nov 7 05:32:30 PST 2013


This is something different. When properties depends on each other 
(using bindings), the binding computation is deferred to the first query 
(get() call) of the dependant.  That means, if q depends on p, you can 
call p.set() as many times you want, but the recomputation will be 
triggered just before first q.get() call. Also in your second example, 
the second invalidation of s would be practically a no-op.

Of course, this doesn't work if you have a ChangeListener on q, because 
the ChangeListener basically need to do get() in order to compute the 
new property value (which is passed as an argument to it's method).

When it's not a property you want to recompute, but an internal state 
(you use to setup the children), layoutChildren() should be the method 
for you.

-Martin

On 11/07/2013 02:08 PM, Tomas Mikula wrote:
> On Thu, Nov 7, 2013 at 11:58 AM, John Hendrikx <hjohn at xs4all.nl> wrote:
>> Hm, I found it googling, and since it showed up here:
>>
>> http://docs.oracle.com/javafx/2/api/javafx/scene/Scene.ScenePulseListener.html
>>
>> I figured it was public, but I just noticed the class is defined package
>> private.
> Although not part of the public API, you can use
>
>      import com.sun.javafx.tk.TKPulseListener;
>      import com.sun.javafx.tk.Toolkit;
>
>      Toolkit.getToolkit().addSceneTkPulseListener(new TKPulseListener(){...})
>
>
> Anyway, I don't think deferring property invalidation until the next
> pulse is very useful in general, for the following reasons:
>
> 1) It can lead to inconsistent observable state of your objects.
> Consider an object with properties p, q, where the value of q depends
> on the value of p, and consider changing the value of p. Now, right
> after
>      p.set(x);
> returns, the state of the object is inconsistent until the next pulse,
> and this inconsistency is observable to the outside world.
>
> 2) It doesn't (in general) avoid recalculations. Consider properties
> p, q, r, s, whose invalidation listeners are deferred until the next
> pulse, with bindings
>      p <- q <- r <- s
>      p <- s
> and consider changing the value of p in pulse 0. The invalidation
> listeners will fire as follows:
> pulse 1: p
> pulse 2: q, s
> pulse 3: r
> pulse 4: s
> As you see, the listeners of s are called twice, causing potentially
> expensive recalculation.
>
> For these reasons, I'm in favor of the approach suggested by Yennick,
> where you "commit" the properties yourself.
>
> Regards,
> Tomas



More information about the openjfx-dev mailing list