1 7 package org.ejtools.swing.table; 8 9 import java.awt.event.InputEvent ; 10 import java.awt.event.MouseAdapter ; 11 import java.awt.event.MouseEvent ; 12 import java.util.Date ; 13 import java.util.Vector ; 14 15 import javax.swing.JTable ; 16 import javax.swing.event.TableModelEvent ; 17 import javax.swing.table.JTableHeader ; 18 import javax.swing.table.TableColumnModel ; 19 import javax.swing.table.TableModel ; 20 21 25 public class TableModelSorter extends TableModelIndexed 26 { 27 28 protected boolean ascending = true; 29 30 protected int column = -1; 31 32 protected int compares; 33 34 protected Vector sortingColumns = new Vector (); 35 36 37 42 public TableModelSorter(TableModel model) 43 { 44 super(model); 45 this.reallocateIndexes(); 46 } 47 48 49 56 public void addMouseListenerToHeaderInTable(JTable table) 57 { 58 final TableModelSorter tableSorter = this; 59 final JTable tableView = table; 60 tableView.setColumnSelectionAllowed(false); 61 MouseAdapter listMouseListener = 62 new MouseAdapter () 63 { 64 public void mouseClicked(MouseEvent e) 65 { 66 TableColumnModel columnModel = tableView.getColumnModel(); 67 int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 68 int column = tableView.convertColumnIndexToModel(viewColumn); 69 if (e.getClickCount() == 1 && column != -1) 70 { 71 int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK; 72 boolean ascending = (shiftPressed == 0); 73 tableSorter.sortByColumn(column, ascending); 74 } 75 } 76 }; 77 JTableHeader th = tableView.getTableHeader(); 78 th.addMouseListener(listMouseListener); 79 } 80 81 82 83 public void checkModel() 84 { 85 if (indexes.length != model.getRowCount()) 86 { 87 System.err.println("Sorter not informed of a change in model."); 88 } 89 } 90 91 92 99 public int compare(int row1, int row2) 100 { 101 this.compares++; 102 for (int level = 0; level < this.sortingColumns.size(); level++) 103 { 104 Integer column = (Integer ) this.sortingColumns.elementAt(level); 105 int result = this.compareRowsByColumn(row1, row2, column.intValue()); 106 if (result != 0) 107 { 108 return this.ascending ? result : -result; 109 } 110 } 111 return 0; 112 } 113 114 115 116 124 public int compareRowsByColumn(int row1, int row2, int column) 125 { 126 Class type = this.model.getColumnClass(column); 127 TableModel data = this.model; 128 129 Object o1 = data.getValueAt(row1, column); 131 Object o2 = data.getValueAt(row2, column); 132 133 if (o1 == null && o2 == null) 135 { 136 return 0; 137 } 138 else if (o1 == null) 139 { 140 return -1; 142 } 143 else if (o2 == null) 144 { 145 return 1; 146 } 147 148 156 if (Comparable .class.isAssignableFrom(type)) 157 { 158 Comparable n1 = (Comparable ) data.getValueAt(row1, column); 159 Comparable n2 = (Comparable ) data.getValueAt(row2, column); 160 161 int result = n1.compareTo(n2); 162 163 if (result < 0) 164 { 165 return -1; 166 } 167 else if (result > 0) 168 { 169 return 1; 170 } 171 else 172 { 173 return 0; 174 } 175 } 176 else if (Number .class.isAssignableFrom(type)) 177 { 178 Number n1 = (Number ) data.getValueAt(row1, column); 179 double d1 = n1.doubleValue(); 180 Number n2 = (Number ) data.getValueAt(row2, column); 181 double d2 = n2.doubleValue(); 182 183 if (d1 < d2) 184 { 185 return -1; 186 } 187 else if (d1 > d2) 188 { 189 return 1; 190 } 191 else 192 { 193 return 0; 194 } 195 } 196 else if (type == Date .class) 197 { 198 Date d1 = (Date ) data.getValueAt(row1, column); 199 long n1 = d1.getTime(); 200 Date d2 = (Date ) data.getValueAt(row2, column); 201 long n2 = d2.getTime(); 202 203 if (n1 < n2) 204 { 205 return -1; 206 } 207 else if (n1 > n2) 208 { 209 return 1; 210 } 211 else 212 { 213 return 0; 214 } 215 } 216 else if (type == String .class) 217 { 218 String s1 = (String ) data.getValueAt(row1, column); 219 String s2 = (String ) data.getValueAt(row2, column); 220 int result = s1.compareTo(s2); 221 222 if (result < 0) 223 { 224 return -1; 225 } 226 else if (result > 0) 227 { 228 return 1; 229 } 230 else 231 { 232 return 0; 233 } 234 } 235 else if (type == Boolean .class) 236 { 237 Boolean bool1 = (Boolean ) data.getValueAt(row1, column); 238 boolean b1 = bool1.booleanValue(); 239 Boolean bool2 = (Boolean ) data.getValueAt(row2, column); 240 boolean b2 = bool2.booleanValue(); 241 242 if (b1 == b2) 243 { 244 return 0; 245 } 246 else if (b1) 247 { 248 return 1; 250 } 251 else 252 { 253 return -1; 254 } 255 } 256 else 257 { 258 String comp1 = o1.toString(); 259 String comp2 = o2.toString(); 260 261 int result = comp1.compareTo(comp2); 262 263 if (result < 0) 264 { 265 return -1; 266 } 267 else if (result > 0) 268 { 269 return 1; 270 } 271 else 272 { 273 return 0; 274 } 275 } 276 } 277 278 279 284 public int getColumn() 285 { 286 return this.column; 287 } 288 289 290 297 public Object getValueAt(int aRow, int aColumn) 298 { 299 this.checkModel(); 300 return super.getValueAt(aRow, aColumn); 301 } 302 303 304 309 public boolean isAscending() 310 { 311 return this.ascending; 312 } 313 314 315 316 public void n2sort() 317 { 318 for (int i = 0; i < getRowCount(); i++) 319 { 320 for (int j = i + 1; j < getRowCount(); j++) 321 { 322 if (compare(indexes[i], indexes[j]) == -1) 323 { 324 this.swap(i, j); 325 } 326 } 327 } 328 } 329 330 331 332 333 public void reallocateIndexes() 334 { 335 int rowCount = model.getRowCount(); 336 this.indexes = new int[rowCount]; 337 338 for (int row = 0; row < rowCount; row++) 340 { 341 indexes[row] = row; 342 } 343 } 344 345 346 353 public void setValueAt(Object aValue, int aRow, int aColumn) 354 { 355 this.checkModel(); 356 super.setValueAt(aValue, aRow, aColumn); 357 } 358 359 360 361 374 public void shuttlesort(int from[], int to[], int low, int high) 375 { 376 if (high - low < 2) 377 { 378 return; 379 } 380 int middle = (low + high) / 2; 381 382 this.shuttlesort(to, from, low, middle); 383 this.shuttlesort(to, from, middle, high); 384 385 int p = low; 386 int q = middle; 387 388 404 if (high - low >= 4 && this.compare(from[middle - 1], from[middle]) <= 0) 405 { 406 for (int i = low; i < high; i++) 407 { 408 to[i] = from[i]; 409 } 410 return; 411 } 412 413 for (int i = low; i < high; i++) 415 { 416 if (q >= high || (p < middle && this.compare(from[p], from[q]) <= 0)) 417 { 418 to[i] = from[p++]; 419 } 420 else 421 { 422 to[i] = from[q++]; 423 } 424 } 425 } 426 427 428 433 public void sort(Object sender) 434 { 435 this.checkModel(); 436 437 this.compares = 0; 438 this.shuttlesort((int[]) indexes.clone(), indexes, 0, indexes.length); 441 } 443 444 445 446 451 public void sortByColumn(int column) 452 { 453 this.sortByColumn(column, true); 454 } 455 456 457 463 public void sortByColumn(int column, boolean ascending) 464 { 465 this.ascending = ascending; 466 this.sortingColumns.removeAllElements(); 467 this.sortingColumns.addElement(new Integer (column)); 468 this.sort(this); 469 super.tableChanged(new TableModelEvent (this)); 470 } 471 472 473 478 public void tableChanged(TableModelEvent event) 479 { 480 this.reallocateIndexes(); 481 super.tableChanged(event); 486 } 487 } 488 | Popular Tags |