Time for action – sorting items in a viewer

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.

  1. JFace structured viewers allow view-specific sorting with the 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;
     }
    }
  2. Hook it up to the viewer as follows:
    treeViewer.setComparator(new TimeZoneViewerComparator());
  3. Run the Eclipse instance, open the Time Zone Tree View, and the TimeZones should be sorted first by offset, then alphabetically:
    Time for action – sorting items in a viewer
  4. To add a viewer-specific sort, modify the 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;
  5. To see the effect of this sort, set the 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());
  6. Re-launch the Eclipse instance, and the view should be in the reverse order.

What just happened?

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset