TableView filtering and sorting (was Re: FilteredList/SortedList)

Richard Bair richard.bair at oracle.com
Mon Jan 14 19:11:00 PST 2013



On Jan 14, 2013, at 5:34 AM, Martin Sladecek <martin.sladecek at oracle.com> wrote:

> On 01/10/2013 06:00 PM, Richard Bair wrote:
>>> This doesn't have to break. All existing APIs are View-based.  The current API for setting the items in the table is assumed to be setting the View, since when sorting it is updated in place.
>>> 
>>> There currently isn't any API for setting a model independent of the view, so one could be added.  As long as the list added via the new method is not modified in place and the existing APIs set and return the items in "view" order.. all is well.
>>> 
>>> We need about four new APIs.
>>> void setModel(ObservableList)
>>> ObservableList getModel()
>>> int getModelIndex(int viewIndex)
>>> int getViewIndex(int modelIndex)
>>> 
>>> Sorting happens internally on the "Items" list, not the "Model" list.
>>> If you call setModel(), a view list ("Items") is created for you and anything you may have set it to previously is toast.
>>> 
>>> If you call setItems(), indicating you wish to use the old API, the model could be forced to null, or a copy of the view list could be made in it's place.  But you have two APIs that are overlapping slightly. That's just what you have to live with.
>>> 
>>> Any existing APIs continue to work based on view coordinates.
>> So, the obvious issues:
>>    - As you mentioned the APIs overlap slightly. Or even if they don't the names are ambiguous so there is some sadness that would just have to be lived with
>>    - Because "items" is mutable, we actually have all the same problems Martin is trying to avoid. For example, if the list has been sorted, and you insert an item at a specific location in the items list, then what happens? Once the TableView supports UI for filtering, and you insert and item into items, then what happens?
> The items would be mutable only when set directly using the setItems() methods. It would be user's responsibility to handle that correctly, if he provided a mutable list as "items".
> Otherwise, the items would be created immutable for the provided model.

That would break current users who can:

getItems().setAll(...)

?

> It's the same with your approach. We have either mutable list as items (set directly) or an immutable one (wrapper). There will be some ambiguity in the API and different approach will have to be used when model is set directly, or in your case, when a wrapper is used.
> E.g. if we want to scroll to a specific element (which is, as you called it, a model based method).
> When view == model, which in both cases means setItems was called with our list, then you can use scrollTo directly with the index from our list.

Really I want a mutable ObservableList for filtering. That was the original intent :-(. Or do you mean we have to deal with unmodifiable lists in either case?

> In case we do not wish TableView to modify our model, we need to treat "model-based" API differently. In case of what Scott proposed, it would be like this (say we have some the index stored in listIndex property):
> 
> view.setModel(list);
> ...
> view.scrollTo(view.getViewIndex(listIndex));
> 
> ...in case of your API:
> 
> WrapperList wrapper = new WrapperList(list);
> view.setItems(wrapper);
> ...
> view.scrollTo(wrapper.fromSourceIndex(listIndex));
> 
> I'm afraid we have no other option if we do not wish to deprecate the items property.

Right, in my case where there is only "items", the items are always view based and if you want to map you use an API on the list vs on the control. But none of the mapping concepts are on any control, just relegated to the list.

Richard


More information about the openjfx-dev mailing list