On 11/07/2013 03:18 PM, Tomas Mikula wrote:
Hi Martin,

On Thu, Nov 7, 2013 at 2:32 PM, Martin Sladecek
<martin.slade...@oracle.com> wrote:
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.
The point of my first example was inconsistency.
Suppose this scenario (remember, the invalidation listeners of p are
deferred until the next pulse):

[pulse]
...
p.set()
...
q.get() // returned value not consistent with the value of p
...
[pulse]
It is consistent, providing that you use binding API for the computation.

I like my objects to appear consistent to the outside world at all
times, so that the client code doesn't have to deal with the
inconsistencies.

Also in your second example, the second invalidation of
s would be practically a no-op.
It is not if you have an invalidation (or change) listener registered on s.
Only in case of change listener. Invalidation listener would not validate/recompute s.

-Martin

Tomas

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 <hj...@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


Reply via email to