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