On 01/22/2014 11:27 AM, Tom Schindl wrote:
On 22.01.14 11:07, Martin Sladecek wrote:
Hi all,
I would like to start discussion about an addition to API in Observable,
ObservableValue and all Observable collections.
There were multiple requests for a way how to avoid duplicates in
listeners lists. The way RT-25613 solves this is that it introduces
public boolean hasListener(ListenerType listener) which would return
true if the provided listener is already registered.

This has one significant drawback that all of Observable* are actually
interfaces. Means we can only add hasListener as a defender method. The
problem is with the default implementation. We cannot return anything
meaningful, so we have to throw an UnsupportedOperationException. The
problem is that this might blow up unexpectedly when some "older"
Observable implementation is used. Also, it might be easy to miss when
implementing the interface, since the IDE might not force you to
implement it.

So as an alternative solution, I propose adding something like:

ensureListener(ListenerType listener)

which would make sure the listener is on the list and if a listener is
already present, the number of times listener is registered on the
Observable will NOT grow after this call.

The default implementation (for Observable) would look like this:

public default void ensureListener(InvalidationListener listener) {
     removeListener(listener);
     addListener(listener);
}

subclasses might do something more effective. The same would apply to
ObservableValue and ChangeListener and Observable[List|Set|Map] and
[List|Set|Map]ChangeListener.
Well this would destroy the order! I expect listeners to be called in
the correct order not? Why doing a remove and not simply check if the
listener has already been added?

Tom

Because there's no way to do it in the interface, hence the problem with hasListener default implementation.

Yes, the order would be broken, but it's actually not guaranteed. Although FX internally uses a List, 3rd party implementations of Observable or ObservableValue might use a Set for listeners for example. This was the idea, but funnily enough, the current Observable javadoc is quite strict on the duplicates which would rule out the Set:

    /**
* Adds an {@link InvalidationListener} which will be notified whenever the
     * {@code Observable} becomes invalid. 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.

Personally, I would rather make this requirement less strict and allow both List backed and Set backed implementations.

-Martin

Reply via email to