作者:张明星 时间:2006.04.07. MSN:
fastzch@hotmail.comextremeComponents是一个十分不错的WEB层显示表格的好东东,其功能十分强大,而且对个性化支持也很好,自己可以做很多的扩展。相关的资料要查看官方网站(
http://www.extremecomponents.org)。
extremeComponents提供了诸多的接口,其中有一个接口就是为了实现排序而出现的,接口如下:
1 public interface SortRowsCallback {
2  public Collection sortRows(TableModel model, Collection rows) throws Exception;
3 } 
同时,在标签中需指明排序所用的接口,代码如下:
1 <ec:table  var="pres"  action="/showNews.do"  sortRowsCallback="demo.MySortCallback"  />
2 
经过我的一番研究,在排序时,extremeComponents使用的是org.apache.commons.beanutils.BeanComparator这个类作为实现的比较器,同时也使用了ReverseComparator,NullComparator等类,官方的实现可以参见org.extremecomponents.table.callback.ProcessRowsCallback文件(这个文件实现了三个接口,分别是RetrieveRowsCallback, FilterRowsCallback, SortRowsCallback,我们在这里只用实现SortRowsCallback就够了)。问题的关键就在于NullComparator这个类,如果你对JAVA基础很熟悉的话,你就会知道JAVA的排序时都会有一个Comparator,在这里就不多讲了,有兴趣的读者可以去看JDK的源码。
经过我的几次追踪,发现排序的最终实现交给了Arrays类的mergeSort方法,这个方法是一个静态的方法,有两个实现,这里用到的是一个带Comparator的实现,具体代码如下:
 1 private static void mergeSort(Object src[], Object dest[],
 2                                   int low, int high, int off, Comparator c) {
 3     int length = high - low;
 4 
 5     // Insertion sort on smallest arrays
 6     if (length < INSERTIONSORT_THRESHOLD) {
 7         for (int i=low; i<high; i++)
 8         for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
 9             swap(dest, j, j-1);
10         return;
11     }
12 
13         // Recursively sort halves of dest into src
14         int destLow  = low;
15         int destHigh = high;
16         low  += off;
17         high += off;
18         int mid = (low + high) >> 1;
19         mergeSort(dest, src, low, mid, -off, c);
20         mergeSort(dest, src, mid, high, -off, c);
21 
22         // If list is already sorted, just copy from src to dest.  This is an
23         // optimization that results in faster sorts for nearly ordered lists.
24         if (c.compare(src[mid-1], src[mid]) <= 0) {
25            System.arraycopy(src, low, dest, destLow, length);
26            return;
27         }
28 
29         // Merge sorted halves (now in src) into dest
30         for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
31             if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
32                 dest[i] = src[p++];
33             else
34                 dest[i] = src[q++];
35         }
36     }
仔细看看,不难发现,问题的关键就在于使用的Comparator 的compare方法。
由此,找到了解决问题的根本办法,实现自己的Comparator 类,我的实现如下:
 1 package demo;
 2 
 3 import org.apache.commons.collections.comparators.NullComparator;
 4 public class MyComparator extends NullComparator{
 5 
 6     public int compare(Object object, Object object1) {
 7         String s1=(String)object;
 8         String s2=(String)object1;
 9         
10         return s1.compareToIgnoreCase(s2);
11     }
12 }
13 
看看,是不是超级简单?答案是肯定的(你或许会说,弄了半天就这么简单呀)。
再来看看我对SortRowsCallback接口的实现,代码如下:
 1 package demo;
 2 
 3 import java.util.*;
 4 
 5 import org.apache.commons.beanutils.BeanComparator;
 6 import org.apache.commons.collections.comparators.ReverseComparator;
 7 import org.extremecomponents.table.bean.Column;
 8 import org.extremecomponents.table.core.TableConstants;
 9 import org.extremecomponents.table.core.TableModel;
10 import org.extremecomponents.table.callback.SortRowsCallback;
11 import org.extremecomponents.table.limit.Sort;
12 
13 public final class MySortCallback implements SortRowsCallback {
14 
15     public Collection sortRows(TableModel model, Collection rows)
16             throws Exception {
17         boolean sorted = model.getLimit().isSorted();
18 
19         if (!sorted) {
20             return rows;
21         }
22 
23         Sort sort = model.getLimit().getSort();
24         String sortProperty = sort.getProperty();
25         String sortOrder = sort.getSortOrder();
26         Column column = model.getColumnHandler().getColumnByAlias(sortProperty);
27         String property = column.getProperty();
28 
29         if (sortOrder.equals(TableConstants.SORT_ASC)) {
30             BeanComparator comparator = new BeanComparator(property,
31                     new MyComparator());
32             Collections.sort((List) rows, comparator);
33         } else if (sortOrder.equals(TableConstants.SORT_DESC)) {
34             BeanComparator reversedNaturalOrderBeanComparator = new BeanComparator(
35                     property, new ReverseComparator(new MyComparator()));
36             Collections.sort((List) rows, reversedNaturalOrderBeanComparator);
37         }
38 
39         return rows;
40     }
41 
42  }
好了,大功告成。
PS:别忘了在标签中设置你自己定义的接口哟。
	
posted on 2006-04-07 21:34 
Robin's Programming World 阅读(3401) 
评论(6)  编辑  收藏  所属分类: 
Java