FilteredList/SortedList

Knut Arne Vedaa knut.arne.vedaa at broadpark.no
Fri Jan 4 13:53:38 PST 2013


Jonathan Giles wrote:
> When designing API it is my goal to try to give the most useful API I
> can. I think that, in the case of SortedList, if I can special case it
> to, for example, allow for returning back to an unsorted state (which is
> something I get asked for a lot), it is worth having it in there (rather
> than requiring a developer to manually watch for the tableview sortOrder
> list to become empty and then set the tableview items list based on the
> sortedList.getOriginalSource(), or, even worse in the case of
> ObservableList, maintain a copy of their original unsorted items list).
> Returning to an unsorted state when there are no columns being sorted is
> what a user expects, so it seems like a reasonable thing to support by
> default if I can?

Yes. With the design I'd consider ideal, you'll get this (revert to 
unsorted state) for free, without any special casing.

I'd suggest that TableView has (in kind of pseudo-code):

// the original as in the current impl
public ObservableList itemsList

// actually a SortedList, but the API user doesn't need to know that
public ObservableList sortedList

// not sure if there's a reason to have this public
private ObservableList displayList

(Now I'm not sure if there is API for enabling/disabling sorting, 
couldn't find it, but I think there should be.)

So:

// create your observable comparator and mutate it on demand
ObservableValue[Comparator] observableComparator =
new ObjectBinding[Comparator] { ...  // create your comparator in here }

// update this whenever itemsList is set by the user
sortedList = itemsList.transform.sorted(observableComparator)	

if (sortEnabled) displayList = sortedList
else displayList = itemsList

// when you want to revert to original
if (revertToOriginalSort) displayList = itemsList	

Then the user can also user the TableView as a sort "function" with 
itemsList as the input and sortedList as the output.

> I'm not entirely clear here with what you're saying. Using the same
> SortedList for three TableViews (based on the current impl in 2.x) will
> result in the display of all three tables being synchronized when
> sorting happens in any one of them. I have a feeling we're saying the
> same thing, but I just wanted to be clear.

Yes, I was talking about a possible future API, not the current 
behaviour with which you wouldn't be able to achieve the use case.

> Also, I'm not entirely sure this isn't what you'd expect. The flip side
> of your argument is the people who put one list into multiple tableviews
> and are confused when their state is not modified across all three.
> Personally I would probably fall into this camp. One rule we try to have
> in JavaFX is to not do any magic if we can help it - so wrapping a list
> (and presumably returning that wrapped list on getItems() calls) would
> be at least a little confusing (i.e. when getItems() does not
> necessarily equal setItems(items)).

I agree with the less magic philosophy, but I think sort-in-place is 
actually _more_ magic.

As I sketched above, don't return the wrapped list on getItem(), return 
the original list there, and return the wrapped list on getSortedList() 
or something similarly named.

> Once you start having view models and data models you end up with all
> kinds of ugliness. For a long time TableView actually did this (before
> being released in 2.0). You inevitably end up with API to convert
> between view and data indices, and it all becomes quite painful and
> confusing really quickly. This was why we decided to simplify the
> approach, by 1) saying that, by default, the view model is the data
> model, and 2) moving to an approach where the separation of data and
> view is handled at the data structure level (e.g.
> ObservableList/TransformationList/SortedList/FilteredList/etc), rather
> than the UI control level. It was unfortunate we couldn't get the
> special collections into 2.0, but I'm pleased they're on their way into
> 8.0.
>
> Of course, my preference is to special case as little as possible - I'm
> just trying to work out where the edge cases may be that would require,
> or benefit from, special cases.

I agree, and I think using SortedList the way I've sketched will get you 
to 2).

I *think* it would be SortedList's responsibility to convert indices 
(i.e. if you at an item to a SortedList at a specific index, it should 
you where to add it (and do that) on it's source), but I'll admit I 
haven't thought it all the way through yet.



Knut Arne Vedaa


More information about the openjfx-dev mailing list