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

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.

主站蜘蛛池模板: 白朗县| 绥阳县| 凤台县| 乳山市| 姜堰市| 巴林右旗| 吴堡县| 庄浪县| 常宁市| 阳原县| 连云港市| 区。| 光山县| 江城| 石首市| 高雄县| 晋中市| 淮滨县| 长宁县| 班玛县| 扎鲁特旗| 余江县| 潼南县| 临沧市| 保定市| 沂南县| 南江县| 新宁县| 岳阳市| 桦甸市| 新竹市| 板桥市| 阳东县| 合山市| 康定县| 新乡县| 金乡县| 四川省| 瑞昌市| 外汇| 京山县|