14.5 表格的排序(ViewerSorter类)
本节实例将实现表格的单击表头排序功能(以ID、姓名两字段的排序为例),本节实例在前面几节的代码基础上修改完成(完整代码见配书光盘的TableViewer4.java文件)。
14.5.1 编写排序器ViewerSorter
TableViewer是根据排序器ViewerSorter中的设置来进行排序的,所以编写ViewerSorter类是排序的关键。编写排序器的代码如下:
//------文件名:MySorter.java-----------
public class MySorter extends ViewerSorter {
// 每列对应一个不同的常量,正数表示要升序、相反数表示要降序
private static final int ID = 1;
private static final int NAME = 2;
//给外界使用排序器对象
public static final MySorter ID_ASC=new MySorter(ID);
public static final MySorter ID_DESC=new MySorter(-ID);
public static final MySorter NAME_ASC=new MySorter(NAME);
public static final MySorter NAME_DESC=new MySorter(-NAME);
// 当前所要排序的列,取自上面的ID、NAME两值或其相反数
private int sortType;
// 构造函数用private,表示不能在外部创建MySorter对象
private MySorter(int sortType) {
this.sortType = sortType;
}
// 最关键的比较方法compare,改写自ViewerSorter。方法返回值是一个int值:正数则
//obj1移到obj2之前;零则obj1和obj2的位置不动;负数则obj1移到obj2之后
public int compare(Viewer viewer, Object obj1, Object obj2) {
// 传入两条记录(实体类),然后依列给出它们的先后顺序
PeopleEntity o1 = (PeopleEntity) obj1;
PeopleEntity o2 = (PeopleEntity) obj2;
switch (sortType) {
case ID: {
Long l1 = o1.getId();
Long l2 = o2.getId();
// Long的compareTo方法返回值有三个可能值1,0,-1:
//如l1>l2则返回1;如l1=l2则返回0;如l1<l2则返回-1
return l1.compareTo(l2);
}
case -ID: {
Long l1 = o1.getId();
Long l2 = o2.getId();
return l2.compareTo(l1);
}
case NAME: {
String s1 = o1.getName();
String s2 = o2.getName();
return s1.compareTo(s2);
}
case -NAME: {
String s1 = o1.getName();
String s2 = o2.getName();
return s2.compareTo(s1);
}
}
return 0;
}
}
程序说明:排序器的代码虽多,但要点就两个。
● 要用MySorter类生成4个不同的排序对象:ID列的升序、ID列的降序、姓名列的升序、姓名列的降序,那么MySorter首先就要解决如何生成这4个不同的排序对象。方法就是让不同的列对应不同的int值,而int值的正负数对应升、降序,然后根据MySorter类构造函数传入的int值就可以判断生成不同的排序器对象。另外,由于MySorter是无状态类,所以多个表格可以安全地共享MySorter所提供的4个排序器对象。
● 排序的算法由MySorter类的compare方法负责,它实际调用的是JDK中同类型对象之间进行比较的compareTo方法,TableViewer则根据MySorter返回的int值来进行记录的排序。
14.5.2 为表格列添加事件监听器
表格列是TableColumn对象,把原来新增ID列和姓名列的4句代码修改如下:
// layout.addColumnData(new
ColumnWeightData(13));// ID列宽13像素
// new TableColumn(table,
SWT.NONE).setText("ID号");
// layout.addColumnData(new ColumnWeightData(40));
// new TableColumn(table, SWT.NONE).setText("姓名");
layout.addColumnData(new ColumnWeightData(13));
TableColumn col1 = new TableColumn(table, SWT.NONE);
col1.setText("ID号");
col1.addSelectionListener(new SelectionAdapter() {
boolean asc = true; // 记录上一次的排序方式,默认为升序
public void widgetSelected(SelectionEvent e) {
// asc=true则ID的升序排序器,否则用降序
tv.setSorter(asc ? MySorter.ID_ASC : MySorter.ID_DESC);
asc = !asc;// 得到下一次排序方式
}
});
layout.addColumnData(new ColumnWeightData(40));
TableColumn col2 = new TableColumn(table, SWT.NONE);
col2.setText("姓名");
col2.addSelectionListener(new SelectionAdapter() {
boolean asc = true;
public void widgetSelected(SelectionEvent e) {
tv.setSorter(asc ? MySorter.NAME_ASC : MySorter.NAME_DESC);
asc = !asc;
}
});






