The TreeViewer
is already showing data in a sorted format, but this is not a view-imposed sort. Because the data is stored in a TreeMap
, the sort ordering is created by the TreeMap
itself, which in turn is sorting on the value of toString()
. To use a different ordering (say, based on offset) the choices are either to modify the TreeMap
to add a Comparator
and sort the data at creation time, or add a sorter to the TreeViewer
. The first choice is applicable if the data is only used by a single view, or if the data is coming from a large external data store, which can perform the sorting more efficiently (such as a relational database). For smaller data sets, the sorting can be done in the viewer itself.
ViewerComparator
. Create a new subclass, TimeZoneViewerComparator
, in the package com.packtpub.e4.clock.ui.internal
, and implement the compare()
method as follows:public class TimeZoneViewerComparator extends ViewerComparator { public int compare(Viewer viewer, Object o1, Object o2) { int compare; if (o1 instanceof TimeZone && o2 instanceof TimeZone) { compare=((TimeZone)o2).getOffset(System.currentTimeMillis()) - ((TimeZone)o1).getOffset(System.currentTimeMillis()); } else { compare = o1.toString().compareTo(o2.toString()); } return compare; } }
treeViewer.setComparator(new TimeZoneViewerComparator());
TimeZones
should be sorted first by offset, then alphabetically:compare()
method of TimeZoneViewerComparator
to get a REVERSE
key from the viewer's data. Use that to invert the results of the sort://The following commented line needs to be removed /*return compare;*/ boolean reverse = Boolean.parseBoolean( String.valueOf(viewer.getData("REVERSE"))); return reverse ? -compare : compare;
REVERSE
key just before the setComparator()
call at the end of the createPartControl()
method of TimeZoneTreeView
.treeViewer.setData("REVERSE",Boolean.TRUE); treeViewer.setComparator(new TimeZoneViewerComparator());
By adding a ViewerComparator
to the Viewer
, the data can be sorted in an appropriate manner for the viewer in question. Typically, this will be done in conjunction with selecting an option in the view—for example, an option may be present to reverse the ordering, or to sort by name or offset.
When implementing a specific Comparator
, check that the method can handle multiple object types (including ones that may not be expected). The data in the viewer may change, or be different at runtime than expected. Use instanceof
to check that the items are of the expected type.
To store properties that are specific to a viewer, use the setData()
and getData()
calls on the viewer itself. This allows a generic comparator to be used across views while still respecting per view filtration/sorting operations.
The preceding example hardcodes the sort data, which requires an Eclipse relaunch to see the effect. Typically, after modifying properties that may affect the view's sorting or filtering, the viewer has a refresh()
invoked to bring the display in line with the new settings.