001 package nl.cwi.sen1.visplugin.table.model; 002 003 004 /** 005 * Table sorter. Sorts a table using comparators 006 * 007 * @author Anton Gerdessen 008 * @date 12-03-2007 009 */ 010 public class TableSorter { 011 SortableTableModel model; 012 013 /** 014 * Constructor. 015 * 016 * @param model The model to sort 017 * @author Anton Gerdessen 018 * @date 12-03-2007 019 */ 020 public TableSorter(SortableTableModel model) { 021 this.model = model; 022 } 023 024 /** 025 * Sort the table on a given column and an order. 026 * 027 * @param column the column to sort on 028 * @param isAscent ascending (true) or or decending (false) order 029 * @author Anton Gerdessen 030 * @date 12-03-2007 031 */ 032 public void sort(int column, boolean isAscent) { 033 int rowCount = model.getRowCount(); 034 int[] indexes = model.getIndexes(); 035 036 // Quicksort 037 for (int rowCounter = 0; rowCounter < rowCount - 1; rowCounter++) { 038 int row1 = rowCounter; 039 for (int row2 = rowCounter + 1; row2 < rowCount; row2++) { 040 // Sort ascending. 041 if (isAscent) { 042 if (compare(column, row2, row1) < 0) { 043 row1 = row2; 044 } 045 // Sort decending. 046 } else { 047 if (compare(column, row2, row1) > 0) { 048 row1 = row2; 049 } 050 } 051 } 052 int tmp = indexes[rowCounter]; 053 indexes[rowCounter] = indexes[row1]; 054 indexes[row1] = tmp; 055 } 056 } 057 058 /** 059 * Compare two values in one column, these two values are the values 060 * at (column, row1) and (column, row2). 061 * 062 * @param column the column to sort on 063 * @param row1 The numbers to compare 064 * @param row2 The numbers to compare 065 * @author Anton Gerdessen 066 * @date 12-03-2007 067 */ 068 private int compare(int column, int row1, int row2) { 069 Object o1 = model.getValueAt(row1, column); 070 Object o2 = model.getValueAt(row2, column); 071 072 // Check for null values, of a null is detected the 'other' is always greater 073 // if both are null return equal 074 if (o1 == null && o2 == null) { 075 return 0; 076 } else if (o1 == null) { 077 return -1; 078 } else if (o2 == null) { 079 return 1; 080 } 081 082 // Determine the data type used in the column and call the compare for that type. 083 // Default is the string compareTo. 084 Class<?> type = model.getColumnClass(column); 085 if (type.getSuperclass() == Number.class) { 086 return compare((Number) o1, (Number) o2); 087 } else if (type == String.class) { 088 return ((String) o1).compareTo((String) o2); 089 } else { 090 return (o1.toString().compareTo(o2.toString())); 091 } 092 } 093 094 /** 095 * Number comparator based on doubles. Return -1 if num2 096 * is greater, 1 if num1 is greater, else 0. 097 * 098 * @param num1 The numbers to compare 099 * @param num2 The numbers to compare 100 * @author Anton Gerdessen 101 * @date 12-03-2007 102 */ 103 private int compare(Number num1, Number num2) { 104 double n1 = num1.doubleValue(); 105 double n2 = num2.doubleValue(); 106 107 if (n1 < n2) { 108 return -1; 109 } else if (n1 > n2) { 110 return 1; 111 } else { 112 return 0; 113 } 114 } 115 116 117 118 }