Reputation: 3186
I was just wondering how JavaFx handles the listeners for an ObservableValue
.
I have a few uncleared things about the Listeners in general:
I am using the listeners and the bindings for a while so i know how to use them(at least I think I know :) ), then I'm not interested in how to use them, since I have to do some more complex listens or bindings I want to clarify some points like I wrote, to be sure I'm using them effectively, and I don't do any unnecessary memory leaks.
I would accept any explanations in this domain, or any good documentation, where I can find answers at leas for these points.
Upvotes: 4
Views: 4521
Reputation: 1842
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);
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
Upvotes: 6