JavaFx:侦听器和/或绑定处理

Sun*_*ame 2 java binding javafx listener javafx-8

我只是想知道JavaFx如何处理的监听器ObservableValue。关于监听器,我总体上有一些不清楚的地方:

  • javaFx如何处理相同值的多个侦听器?据我所知,我可以将多个侦听器添加到同一个obsValue中,那么触发顺序是什么?喜欢在fifo吗?
  • 如果将相同的侦听器(相同的实例)两次添加到同一对象,会被添加两次,会发生什么?如果是,那么它将触发两次?或者我不确定它是如何工作的。
  • 我知道在某些情况下可以用绑定替换侦听器,反之亦然,但是哪个更有效?更好地绑定,还是更好地添加侦听器?

我使用了一段时间的监听器和绑定,所以我知道如何使用它们(至少我想我知道:)),然后我对如何使用它们不感兴趣,因为我必须做一些更复杂的监听或绑定,我想像我写的那样澄清一些要点,以确保我有效地使用它们,并且我不会发生任何不必要的内存泄漏。

我会接受此领域的任何解释或任何好的文档,在这些方面我可以从中找到答案。

d.j*_*own 5

How do javaFx handles multiple listeners on the same value? As I know I can add multiple listeners to the same obsValue, then what is the trigger order? Like in fifo?

What happens if I add the same listener(the same instance) twice to the same object, does is gets added twice? if yes then it triggers twice? Or i'm not sure how it works.

Let us look at the documentation for one part of the answer:

ObservableValue<T>.addListener(ChangeListener<? super T> listener);

Adds a ChangeListener which will be notified whenever the value of the ObservableValue changes.

If the same listener is added more than once, then it will be notified more than once. That is, no check is made to ensure uniqueness.

Note that the same actual ChangeListener instance may be safely registered for different ObservableValues.

The bold section of the statement above tells us all we need to know, adding the same ChangeListener n times will cause it to be fired n times.

The ObservableValue interface does not specify any operations for checking if a ChangeListener already exists. You may be lucky and find an implementation does give you this mechanism, but really it is not of much use. To guarantee you are not adding a duplicate ChangeListener you can do the following:

ChangeListener<...> myListener = ...;
someProperty.removeListener(myListener);
someProperty.addListener(myListener);
Run Code Online (Sandbox Code Playgroud)

In terms of the order executed the ObservableValue interface itself does not specify the order.

Looking at the standard Property classes included in the JavaFX library, e.g. SimpleDoubleProperty, they are fired off in the order added. It is difficult to explain quickly how this is achieved to the slightly complex mechanisms used by classes such as SimpleDoubleProperty. Look at the ExpressionHelper class for more detail on how this is done.

If you were to implement the ObservableValue interface yourself (although this is not advised by the Javadoc) you could specify your own order of execution.


I know there are cases when I can replace listener with binding and vice versa, but which is more effective? Better to bind, or better to add a listener?

Bindings are generally used when you want to bind Property<T> objects together, so for example if you bind propertyB to propertyA (i.e. propertyA.bind(propertyB)) then when propertyB is changed, propertyA will also change. Bindings can be bi-directional as well.

So, if you want a change to effect another Property using a bind makes sense. But note, that properties only reference a single other property through binding. To bind multiple properties you can daisy chain them like a link list (through their bindings) or by using a class that facilitates multiple bindings (e.g. DoubleBinding)

If the above is not the case, add a Listener.

Also see this resource: Using JavaFX Properties and Binding