alspaughb at gmail.com
Wed Jan 16 13:35:42 PST 2013
Sorry if I'm a little late to this discussion since I am still very new
to JavaFX. Have you taken a look at the approach to ObservableLists
that the Glazed Lists project takes?
An issue I see with the TransformationList is that it only provides
sorting and filtering transformations. In general, you could have many
other types of arbitrary list transformations. Those transformations
could depend on multiple ObservableLists or scalar ObservableValues.
See Glazed Lists for more examples of powerful list transformations.
Why not just implement SortedList and FilterList as concrete subclasses
of ListBinding that are bound to their source ObservableList and an
observable Comparator or predicate? For convenience, you could provide
sort and filter methods to ListExpression that take the appropriate
observable Comparator or predicate and return another sorted or filtered
ListExpression so you can chain the calls and build a transformation
This makes it possible to add more methods to ListExpression to provide
more types of list transformations in the future without breaking
anything, and end users can build their own custom transformations
simply by providing a concrete implementation of ListBinding and binding
to the appropriate dependencies.
I haven't had a chance to study the TableView API closely, but you may
be thinking you need a special interface on SortedList so that TableView
can change the Comparator on it when the user wants to change the sort
order. Is that really true? Why can't TableView simply make it's
Comparator properties observable and not be responsible for sorting the
list at all? You could provide a convenient TableComparatorChooser that
registers itself as a listener that responses to changes in the
TableView comparators by updating the observable sort Comparator the
SortedList is bound to appropriately. This borrows some ideas from the
Glazed Lists approach to sorting a table.
From: Martin Sladecek <martin.sladecek at oracle.com>
To: openjfx-dev at openjdk.java.net
Date: Wed, 02 Jan 2013 16:58:26 +0100
I would like to start discussion about a new API for ObservableLists
that are filtered/sorted. This API was already in the repository before
2.0 was released, but was withdrawn (
In the original API, there were 3 new classes: FilteredList, SortedList
and TransformationList (parent of the previous two). These 2 lists took
a different (Observable)List, acting as a view for that list, firing
change notifications when the view changed.
Since we have a different situation now, due to new (overlapping)
features in JDK 8, I'd like to propose a different API for FilteredList
First of all, I don't think we need separate FilteredList and SortedList
classes anymore. With defender methods, we can have a similar approach
to JDK's stream(), having e.g. transform() method on ObservableList,
that would allow filtering & sorting of the list.
The original API allowed "batch" mode, but this is now basically covered
with List's stream(), although it's more cumbersome as you won't get a
List directly of a Stream, not to mention ObservableList, which is what
you need to pass as a model to various controls, like TableView.
Still, I'm not in favour of having this also in FX, but maybe something
like Iterable to ObservableList conversion method would ease the FX
development when using JDK 8 steams...
I want to keep TransformationList to serve both as a common parent for
all current and future "transformation" lists, but also returning
TransformationList on transform() call, having methods like filtered()
and sorted() directly on the TransformationList.
So overall, the new API would look like this:
public abstract class TransformationList<E, F> implements
protected TransformationList(ObservableList<? extends F> source);
public final ObservableList<? extends F> getDirectSource();
// The first non-transformation list in the chain.
public final ObservableList<?> getOriginalSource();
// Called when a change from the source is triggered.
protected abstract void onSourceChanged(Change<? extends F> c);
// Maps the index of this list's element to an index in the direct
public abstract int getSourceIndex(int index);
public final int getOriginalSourceIndex(int index);
public final TransformationList<E, E> filtered(Predicate<? super E>
public final TransformationList<E, E> sorted(Comparator<? super E>
ObservableList<E> interface would get a new defender method:
public TransformationList<E, E> transform();
this would return TransformationList representation of the current list.
Another appoach would be to have filtered(), sorted() directly on
ObservableList as a defender methods, which would remove the necessity
of calling transform() before filtered()/sorted(), but I find the first
one more consistent with JDK API.
More information about the openjfx-dev