[REVIEW REQUEST] Improvements to TableView sorting

Jonathan Giles jonathan.giles at oracle.com
Sun Feb 17 13:36:41 PST 2013


Hi all,

I am wanting to summarise my plans on how to improve TableView sorting 
in JavaFX 8.0, given the conclusions reached regarding the introduction 
of SortedList in JavaFX 8.0 [1]. Apologies for the length of this email. 
If I had more time I would have made it shorter.

OVERVIEW
====================
For a while I've maintained an umbrella issue for improved sorting 
functionality in TableView (RT-19479 [2]). My expectation is what I 
outline below should work towards resolving as many of the issues 
outlined in this Jira issue, most importantly the following features are 
ones I would love to support:

1) Support returning to an unsorted state.
2) Support forcing a 'continuous' sort (so that whenever the items list 
is changed the TableView remains sorted).
3) Support custom sort policies (to allow for people to override the 
current in-memory sort policy and instead, say, go direct to a database 
to do the sort).
4) Be notified of when a sort event is about to occur and prevent it 
from happening.
5) Make it possible to force a sort when something elsewhere in the 
universe (unrelated to the tableview) has changed (e.g. when you know 
the tableview is no longer consistent and should re-run its sort policy).

I'm not aware of other features that should be supported. If you have 
some and they are within the scope of TableView sorting, then please 
read the rest of this email and then reply to it so we can discuss.

IMPLEMENTATION
====================
I have attached an early draft patch for the following functionality 
inside RT-19479. It is 'early and draft' in the sense that I'm fairly 
comfortable with the API, but there is still a lot of implementation and 
javadoc work that needs to be done. Hopefully it should give you all an 
idea of what is planned, so that you may offer any thoughts before I get 
too far into implementation and javadoc.

To summarise the patch, what I've done is add a new SortEvent class, and 
then for both TableView and TreeTableView I have done the following:

  * I've introduced a public static Callback DEFAULT_SORT_POLICY that
    encapsulates the current sorting code. Users are free to overwrite
    this sort policy should they wish to instead go to the database, for
    example. They do this by calling tableView.setSortPolicy(...).
  * I have made the TableView and TreeTableView sort() methods public,
    but they simply defer to the sort policy (assuming it is non-null,
    which is the case by default as the DEFAULT_SORT_POLICY is set by
    default).
  * I have made the code that calls sort() more full-featured. This
    happens in a few places, most notably when the 'sortOrder' list is
    changed (where sortOrder is a list of TableColumns which the user /
    developer has specified are to be used to sort the data in the
    table). In particular, I now do the following when the sortOrder
    changes (or any of the other sort criteria relevant to the sort):
      o I update the Comparator that I am about to use. This Comparator
        is now publicly readable (but not writable), so that people can
        do
        sortedList.comparatorProperty().bind(tableView.comparatorProperty()).
          + The reason why I don't want the comparator to be writable is
            that it would then allow for the comparator to be
            inconsistent with the sortOrder list, whereas I view the
            comparator as a reflection of the sortOrder. If people don't
            want to use this comparator they are free to set their own
            sort policy and use whatever they want in there.
      o I fire the SortEvent. If this event is consumed I do not run the
        sort().
      o I call sort()
      o sort() is now very simple: it calls getSortPolicy() and runs it,
        passing in the TableView / TreeTableView and expecting a boolean
        response to indicate success or failure.

The above outline essentially allows for features 2), 3), 4) and 5) from 
the list above. The only feature missing therefore is 1), which is 
support for returning to an unsorted state. The solution to this is to 
have a special-case support inside TableView / SortedList such that the 
developer may do what I mentioned above (namely, 
sortedList.comparatorProperty().bind(tableView.comparatorProperty())), 
and when the tableView.sortOrder list is empty the TableView / 
SortedList will take that to mean there is no sort desired and to return 
to the original, unsorted state.

The other important note to make is that if you as the developer provide 
the TableView with a SortedList this is telling the TableView not to 
sort the collection or modify the Comparator if the user / developer 
changes the sortOrder (e.g. by clicking on the column headers). In other 
words, a TableView with a SortedList can not have its sort order changed 
by default. Of course, if you DO want the Comparator to be changed in 
your SortedList (and to support unsorted state as above), you can simply 
bind the comparator of the list to the tableview comparator.

I hope that is clear. It's a lot of detail to get out, but hopefully it 
meets the expectations of everyone and I can go forth and implement it 
(and pray for no gnarly edge cases). I think the most probable area for 
issues is around maintaining consistent visuals for the sorted table 
column(s) given the ability for sorting to fail and / or be ignored by 
the developer implementation of the comparator / sort policy.

As always, your thoughts and comments are appreciated, but lets keep 
this discussion focused solely on sorting in TableView (and to a lesser 
degree TreeTableView).

[1] See the last comment by Richard Bair here: 
http://javafx-jira.kenai.com/browse/RT-17053
[2] http://javafx-jira.kenai.com/browse/RT-19479

Thanks,
-- Jonathan


More information about the openjfx-dev mailing list