TableView filtering and sorting (was Re: FilteredList/SortedList)
Martin Sladecek
martin.sladecek at oracle.com
Thu Jan 10 03:40:18 PST 2013
On 01/09/2013 10:27 PM, Scott Palmer wrote:
> On 2013-01-09, at 1:42 PM, Richard Bair <richard.bair at oracle.com> wrote:
>
>> OK, so lets explore what life would look like if we tried to do the sorting internally to the TableView (and everything here also applies to the TreeTableView. ListView and TreeView have no intrinsic UI for sorting, although one could imagine that we would want to add DnD reordering as a feature to both ListView and TreeView, and this would therefore exhibit the same sort of pathologies that we are exploring in TableView. So although we're talking about TableView, all of these issues are actually applicable to TreeView, TableView, ListView, and TreeTableView).
>>
>> I'm not interested in deprecating (although for completeness, I'm glad it came up). So lets see if there is another way to deal with the problem.
>>
>> The following APIs presently refer to either "row" or "index" on TableView:
>> - edit(int row, TableColumn col)
>> - scrollTo(int index)
>> - getEditingCell (returns a TablePosition)
>> - getFocusModel (returns a TableView.TableViewFocusModel)
>> - row factory (creates a TableRow)
>> - getSelectionModel (returns a TableView.TableViewSelectionModel)
>>
>> Each TableRow has an "index"
>> TablePosition has a "row"
>> TableCell has an "index" (to be honest I don't even know what this index is -- row index I would guess?)
>> TableView.TableViewFocusModel has:
>> - focus(int index)
>> - focus(int row, TableColumn col)
>> - getModelItem(int index)
>> - isFocused(int row, TableColumn col)
>> - focus(TablePosition)
>> TableView.TableViewSelectionModel has:
>> - clearAndSelect(int row, TableColumn col)
>> - clearSelection(int row, TableColumn col)
>> - getTableModel() "returns getTableView().getItems()"
>> - getTableView() "returns the table view"
>> - isSelected(int row, TableColumn col)
>> - select(int row, TableColumn col)
>>
>> There might be more "index" / "row" based methods or properties, but I got all the ones I could find. It is a pretty large list! It seems self evident to me that changing the meaning of any of these is going to introduce very serious bugs not only in compatibility but going forward -- developers are constantly going to be stymied. But anyway, let us press on :-).
>>
>> We could say that "anything named 'row' is view based, and anything named 'index' is model based" and then adjust the names of the various API accordingly. This at least would have the benefit of providing guidance in the API names as to whether the integer is model or view based. That at least would make it so that, compatibility breakage aside, future developers would know what is what (after they first get bit, anyway, they will have some means of avoiding future dental encounters).
>>
>> Now the big debate is what each of the various methods means. We could say they are all view based or all model based, and then provide convenience methods to translate. However this scheme will fail. The "index" on a TableRow and a TableCell must be view-based, because this index is used to determine even/odd striping. Therefore, it must be view-based. However we cannot make everything view-based since all existing code will break, since it rightly assumes that the model remains in sync with the view and therefore all indexes are model based.
> 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.
>
> Scott
>
+1. Very similar to what I had in mind. We can say that everything is
view-based and yet nothing will break the existing code, as for the
existing code, model will be the same as the view.
So the items list will be always the reference list for all the indexes
in the API.
For the new code, if somebody has an index from the model, it can be
converted to view index easily.
One downside is that we would need to optimize (at least) sorted() for
fast model to view index conversion, which might require more memory.
But I still think it's a better trade-off than a special single-purpose
wrapper list implementation for the TableView et al.
-Martin
More information about the openjfx-dev
mailing list