The reason why this was decided this way is simple : performance. You usually don't (try to) add a listener twice, so in most cases it doesn't make sense to check for duplicates every time a listener is added. So we currently leave the burden of avoiding duplicates on the developer.

-Martin

On 01/22/2014 11:23 AM, Randahl Fink Isaksen wrote:
Hi Martin

While I agree your proposed solution would work, I still don’t understand why 
JavaFX should keep on supporting duplicates in listener collections. Can anyone 
come up with just 1 example of an application that might be depending on having 
two listeners on the same Observable? E.g. this kind of code:

myObservable.addListener(myChangeListener); //add it
myObservable.addListener(myChangeListener); //add it again

In what kind of situation would this sort of code make any sense?

If we all feel confident that the presence of duplicates listeners is always an 
error, I warmly recommend changing the API to be duplicate free.

Yours

Randahl




On 22 Jan 2014, at 11:07, Martin Sladecek <martin.slade...@oracle.com> 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.

What do you think?

JIRA link: https://javafx-jira.kenai.com/browse/RT-25613

-Martin

Reply via email to