ListChangeListener

Michael Heinrichs michael.heinrichs at oracle.com
Fri Dec 9 02:18:21 PST 2011


Hi Daniel,

thank you very much for your input. Feedback like yours helps us to understand the difficulties user encounter and improve the API.

Unfortunately we will not be able to implement your proposal for some time. ObservableList is an interface and we will not be able to make changes until JDK 8. Even with virtual extension methods in place, we will probably not be able to add the addListener method to ObservableList, because there is no default implementation as far as I can tell.

The other issue is, that you will have a hard time to convince people in the JavaFX team. One of the high level goals for the JavaFX API is to use SAMs as much as possible to benefit from lambda expressions later. You may have noticed that all listeners, event handlers, callbacks etc. in the JavaFX library are SAMs. Convincing people to break this pattern with the ListChangeHandler will be tough. :-)


Now what we can do now and what we should do is improve the documentation. From my experience most ListChangeListeners are actually quite simple, because usually you do not have to test the operation type. For example if you loop over all removed elements, this will also work for an add-operation, because the list of removed elements will be empty. But AFAIK this is not documented so far, I can imagine we need a tutorial or somebody should blog about some common cases and how you can implement them with ListChangeListeners.

Maybe you bumped into some use cases that we are not aware of. Could you please give us some examples? That would be very helpful to understand the difficulties you have encountered.

Thanks,
Michael



On 08.12.2011, at 20:07, Gaja Sutra wrote:

> When trying to write the collections needed by my application and lacking in JavaFX runtime, I have found difficult to use ListChangeListener, because the code to write (the while loop on each change with tests of operation type) is difficult to read. I suggest the following addition to API:
> 
> 1) In ObservableList<E> add the following new method and create the corresponding interface:
> 
> |public void addListener(ListChangeHandler<? super E> obs);|
> 
> |public interface ListChangeHandler<E> {
>    public void begin();
>    public void addedItem(int index, E addedItem);
>    public void addedItems(int from, int to, List<? extends E> readOnlyAddedItems);
>    // ReadOnlyIntList wrap the int[] to be read-only
>    public void swapped(int from, int to, ReadOnlyIntList permutation);
>    public void removedItems(int index, int size, List<? extends E> readOnlyDeletedItems);
>    public void removedItem(int index, E removedItem);
>    public void end();
> }
> |
> 
> 2) Provide a class of utilities methods for ListChangeHandler giving implementation of methods by delegating to it:
> |public class ListChangeUtils {
>    public static void addedItems(ListChangeHandler handler, int from, int to, List<? extends E> readOnlyAddedItems) {
>        for (int i = from; i<to; i++) {
>            handler.addedItem(i, readOnlyAddedItems.get(i-from));
>        }
>    }
> }
> |
> 
> 3) In Java8, with defenders methods <http://cr.openjdk.java.net/%7Ebriangoetz/lambda/Defender%20Methods%20v4.pdf>, add default implementations for all methods excepted the following four methods:
> 
> |public interface ListChangeHandler<E> {
>    public void begin();
>    public void addedItem(int index, E addedItem);
>    public void removedItem(int index, E removedItem);
>    public void end();
> }|
> 
> by having code like this, for other methods, in the preceding interface:
> 
> |    public void addedItems(int from, int to, List<? extends E> readOnlyAddedItems) default ListChangeUtils.||addedItems||;
> |
> 
> 4) Conclusion: I think this will give correct performance by allowing, like with ListChangeListener, to have a specialized handler receiving directly the addition of multiple items (if it support this feature). But if the handler can not have optimized path for this case it will need in current Java to implement addedItems by calling |ListChangeUtils.addedItems(this, from, to, readOnlyAddedItems)| or in Java8 by doing nothing (automatically supported by defender method). This is the symmetric model for receiving notification of changes, like com.sun.javafx.collections.IterableChangeBuilder is for creating changes notification.
> 
> For code readability, I think having one method for each type of operation on list will be much more clean and readable, because the while loop will disappear and each type of operation will correspond to one method of handler separated from others.
> 
> Thanks for your opinions,
> Daniel.
> 



More information about the openjfx-dev mailing list