jonathan.giles at oracle.com
Thu Jan 3 20:08:40 PST 2013
On 4/01/2013 8:39 a.m., Knut Arne Vedaa wrote:
> I'd say: don't special case, don't treat the items list as anything
> else than an ObservableList, don't try to know what you're dealing
> with, don't guess with the API user wants. If they provide a
> SortedList and you wrap it with a new SortedList there will be
> redundancy - but that's the user's responsibility. You provide the
> API, the user may use it or abuse as they wish.
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?
> Let's look at a use case:
> Say you (as API user) have three TableViews beside each other. They
> are all backed by the same list, which happens to be a SortedList (for
> reasons unknown). You want to view them as independently sorted. If
> now the TableView says "aha! we already have a sorted list, so we can
> just use that for sorting!", obviously all views will be effected by
> the sorting, which is not what you want.
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.
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)).
> The main problem is, of course, that the current behaviour is
> sort-in-place, i.e. mutation of the backing list. I think it's
> unavoidable to change this behaviour, and I also think that is
> actually a good thing, since with the current behaviour you are having
> a "view" mutating the user's data without the API user explicitly
> asking for it.
> If you actually *want* the TableView to be able to be a
> "sorter-of-data" and not just a "displayer-of-data" (optionally
> sorted), you could have a getSortedList() method that returns a
> reference to the internally sorted list.
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.
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.
More information about the openjfx-dev