官术网_书友最值得收藏!

Time for action – sorting items in a viewer

The TreeViewer already shows data in a sorted list, 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 the toString method. To use a different ordering (say, based on the timezone 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 called TimeZoneViewerComparator in the com.packtpub.e4.clock.ui.internal package, and implement the compare method as follows:
    public class TimeZoneViewerComparator extends ViewerComparator {
     public int compare(Viewer viewer, Object z1, Object z2) {
      int compare;
      if (z1 instanceof ZoneId && z2 instanceof ZoneId) {
        Instant now = Instant.now();
        ZonedDateTime zdt1 = ZonedDateTime.ofInstant(now,(ZoneId)z1);
        ZonedDateTime zdt2 = ZonedDateTime.ofInstant(now,(ZoneId)z2);
        compare = zdt1.compareTo(zdt2);
      } else {
        compare = o1.toString().compareTo(o2.toString());
      }
      return compare;
     }
    }
  2. Set the comparator on the treeViewer in the TimeZoneTreeView as follows:
    treeViewer.setComparator(new TimeZoneViewerComparator());
  3. Run the Eclipse instance, open the Time Zone Tree View, and the time zones should be sorted first by offset, then alphabetically:
  4. To add a viewer-specific sort, modify the compare method of the TimeZoneViewerComparator class to get a REVERSE key from the viewer's data. Use it to invert the results of the sort:
    // 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 create 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 the TimeZoneViewerComparator to the TimeZoneTreeViewer, 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.

Tip

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 run-time 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 hard-codes the sort data, which requires an Eclipse re-launch to see the effect. Typically after modifying properties that may affect the view's sorting or filtering, refresh is invoked on the viewer to bring the display in line with the new settings.

主站蜘蛛池模板: 疏附县| 廉江市| 徐水县| 泾源县| 于田县| 商洛市| 左贡县| 岗巴县| 恩平市| 农安县| 普兰店市| 安新县| 精河县| 安远县| 开化县| 葵青区| 东兰县| 儋州市| 敖汉旗| 武威市| 巴南区| 衡水市| 马龙县| 华安县| 凤山县| 米脂县| 福海县| 松桃| 于都县| 桃江县| 连南| 当阳市| 屏边| 南部县| 曲阳县| 航空| 尖扎县| 邯郸市| 内丘县| 武乡县| 西乌珠穆沁旗|