1 package org.lucane.applications.jmail.base; 2 3 22 23 import java.awt.event.*; 24 import java.text.*; 25 import java.util.*; 26 import javax.swing.*; 27 import javax.swing.event.*; 28 import javax.swing.table.*; 29 30 36 final class SortableTable extends JTable 37 { 38 39 private Object rowData[][]; 40 41 42 private Object columnsNames[]; 43 44 45 private Object indexes[]; 46 47 48 private int rowIndexes[]; 49 50 51 private int[] sortingColumns; 52 53 54 private boolean ascending; 55 56 57 private ArrayList listeners; 58 59 60 protected SortableTable() 61 { 62 super(); 63 64 ascending = true; 65 listeners = new ArrayList(); 66 67 init(); 68 } 69 70 74 protected SortableTable(Object rowData[][], Object columnsNames[]) 75 { 76 super(rowData, columnsNames); 77 78 this.rowData = rowData; 79 this.columnsNames = columnsNames; 80 81 ascending = true; 82 listeners = new ArrayList(); 83 84 init(); 85 } 86 87 93 public final boolean isCellEditable(int row, int col) 94 { 95 return(false); 96 } 97 98 99 private void init() 100 { 101 sortingColumns = null; 102 103 ascending = true; 104 105 listeners = new ArrayList(); 106 107 setShowGrid(false); 109 110 indexes = new Object [0]; 111 rowIndexes = new int[0]; 112 } 113 114 117 protected final void setIndexes(Object indexes[]) 118 { 119 this.indexes = indexes; 120 } 121 122 126 protected final void setData(Object rowData[][], Object columnsNames[]) 127 { 128 this.rowData = rowData; 129 this.columnsNames = columnsNames; 130 131 ((DefaultTableModel)dataModel).setDataVector(rowData, columnsNames); 132 reallocateIndexes(); 133 } 134 135 138 protected final Object getSelectedRowIndex() 139 { 140 return(indexes[getSelectedRow()]); 141 } 142 143 protected final Object [] getSelectedRowsIndexes() 144 { 145 int[] rows = getSelectedRows(); 146 Object indices[] = new Object [rows.length]; 147 148 for(int i = 0; i < rows.length; i++) 149 indices[i] = indexes[rows[i]]; 150 151 return(indices); 152 } 153 154 157 protected final void addListSelectionListener(ListSelectionListener listener) 158 { 159 getSelectionModel().addListSelectionListener(listener); 160 } 161 162 165 protected final void addTableModelListener(TableModelListener listener) 166 { 167 dataModel.addTableModelListener(listener); 168 } 169 170 176 private int compareRowsByColumn(int row1, int row2, int column) 177 { 178 Class type = dataModel.getColumnClass(column); 179 180 DefaultTableModel data = null; 181 182 data = (DefaultTableModel)dataModel; 183 184 Object o1 = data.getValueAt(row1, column); 185 Object o2 = data.getValueAt(row2, column); 186 187 if(o1 == null && o2 == null) 188 return(0); 189 190 else if(o1 == null) 191 return(-1); 192 193 else if(o2 == null) 194 return(1); 195 196 if(type == java.util.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 return(-1); 205 206 else if(n1 > n2) 207 return(1); 208 209 else 210 return(0); 211 } 212 213 else if(type == String .class) 214 { 215 String s1 = (String )data.getValueAt(row1, column); 216 String s2 = (String )data.getValueAt(row2, column); 217 int result = s1.compareTo(s2); 218 219 if(result < 0) 220 return(-1); 221 222 else if(result > 0) 223 return(1); 224 225 else 226 return(0); 227 } 228 229 else 230 { 231 Object v1 = data.getValueAt(row1, column); 232 String s1 = v1.toString(); 233 Object v2 = data.getValueAt(row2, column); 234 String s2 = v2.toString(); 235 int result = s1.compareTo(s2); 236 237 if(result < 0) 238 return(-1); 239 240 else if(result > 0) 241 return(1); 242 243 else 244 return(0); 245 } 246 } 247 248 253 private int compare(int row1, int row2) 254 { 255 for(int level = 0; level < sortingColumns.length; level++) 256 { 257 int result = compareRowsByColumn(row1, row2, sortingColumns[level]); 258 259 if(result != 0) 260 { 261 if(ascending) 262 return(result); 263 264 else 265 return(-result); 266 } 267 } 268 269 return(0); 270 } 271 272 273 private void reallocateIndexes() 274 { 275 int rowCount = dataModel.getRowCount(); 276 277 rowIndexes = new int[rowCount]; 278 279 for(int row = 0; row < rowCount; row++) 280 rowIndexes[row] = row; 281 } 282 283 284 private void sort() 285 { 286 shuttlesort((int[])rowIndexes.clone(), rowIndexes, 0, indexes.length); 287 } 288 289 296 private void shuttlesort(int from[], int to[], int low, int high) 297 { 298 if((high - low) < 2) 299 return; 300 301 int middle = (low + high) / 2; 302 shuttlesort(to, from, low, middle); 303 shuttlesort(to, from, middle, high); 304 305 int p = low; 306 int q = middle; 307 308 if((high - low) >= 4 && compare(from[middle - 1], from[middle]) <= 0) 309 { 310 for(int i = low; i < high; i++) 311 to[i] = from[i]; 312 313 return; 314 } 315 316 for(int i = low; i < high; i++) 317 { 318 if(q >= high || (p < middle && compare(from[p], from[q]) <= 0)) 319 to[i] = from[p++]; 320 321 else 322 to[i] = from[q++]; 323 } 324 } 325 326 329 private void sortByColumn(int column) 330 { 331 sortByColumn(column, true); 332 } 333 334 338 private void sortByColumn(int column, boolean ascending) 339 { 340 this.ascending = ascending; 341 342 sortingColumns = new int[1]; 343 sortingColumns[0] = column; 344 345 sort(); 346 347 ((DefaultTableModel)dataModel).fireTableChanged(new TableModelEvent(dataModel)); 348 } 349 350 351 protected final void addMouseListenerToHeaderInTable() 352 { 353 setColumnSelectionAllowed(false); 354 355 MouseAdapter listMouseListener = new SortableTableListener(this); 356 listeners.add(listMouseListener); 357 358 JTableHeader th = getTableHeader(); 359 th.addMouseListener(listMouseListener); 360 } 361 362 363 protected final void removeListeners() 364 { 365 JTableHeader th = getTableHeader(); 366 367 int size = listeners.size(); 368 369 for(int i = 0; i < size; i++) 370 { 371 SortableTableListener l = (SortableTableListener)listeners.get(i); 372 th.removeMouseListener((MouseListener)l); 373 } 374 } 375 376 381 private void dataSort(int column, boolean ascending) 382 { 383 try 384 { 385 if(ascending) 386 { 387 int j; 388 int limit = rowData.length; 389 int st = -1; 390 391 while(st < limit) 392 { 393 st++; 394 limit--; 395 boolean swapped = false; 396 397 for(j = st; j < limit; j++) 398 { 399 if(rowData[j][column] instanceof String ) 400 { 401 String s1 = (String )rowData[j][column]; 402 String s2 = (String )rowData[j + 1][column]; 403 404 if(s1.compareTo(s2) > 0) 405 { 406 swap(j, (j+1)); 407 swapped = true; 408 409 Object tmpId = new Object (); 410 tmpId = indexes[j]; 411 indexes[j] = indexes[j + 1]; 412 indexes[j + 1] = tmpId; 413 } 414 } 415 416 else if(rowData[j][column] instanceof Date) 417 { 418 DateFormat df = DateFormat.getInstance(); 419 df.setLenient(true); 420 421 Date d1 = (Date)rowData[j][column]; 422 Date d2 = (Date)rowData[j + 1][column]; 423 424 if(d1.after(d2)) 425 { 426 swap(j, (j+1)); 427 swapped = true; 428 429 Object tmpId = new Object (); 430 tmpId = indexes[j]; 431 indexes[j] = indexes[j + 1]; 432 indexes[j + 1] = tmpId; 433 } 434 } 435 } 436 437 if(!swapped) 438 return; 439 440 else 441 swapped = false; 442 443 for(j = limit; --j >= st;) 444 { 445 if(rowData[j][column] instanceof String ) 446 { 447 String s1 = (String )rowData[j][column]; 448 String s2 = (String )rowData[j + 1][column]; 449 450 if(s1.compareTo(s2) > 0) 451 { 452 swap(j, (j+1)); 453 swapped = true; 454 455 Object tmpId = new Object (); 456 tmpId = indexes[j]; 457 indexes[j] = indexes[j + 1]; 458 indexes[j + 1] = tmpId; 459 } 460 } 461 462 else if(rowData[j][column] instanceof Date) 463 { 464 DateFormat df = DateFormat.getInstance(); 465 df.setLenient(true); 466 467 Date d1 = (Date)rowData[j][column]; 468 Date d2 = (Date)rowData[j + 1][column]; 469 470 if(d1.after(d2)) 471 { 472 swap(j, (j+1)); 473 swapped = true; 474 475 Object tmpId = new Object (); 476 tmpId = indexes[j]; 477 indexes[j] = indexes[j + 1]; 478 indexes[j + 1] = tmpId; 479 } 480 } 481 } 482 483 if(!swapped) 484 return; 485 } 486 } 487 488 else 489 { 490 int j; 491 int limit = rowData.length; 492 int st = -1; 493 494 while(st < limit) 495 { 496 st++; 497 limit--; 498 boolean swapped = false; 499 500 for(j = st; j < limit; j++) 501 { 502 if(rowData[j][column] instanceof String ) 503 { 504 String s1 = (String )rowData[j][column]; 505 String s2 = (String )rowData[j + 1][column]; 506 507 if(s1.compareTo(s2) < 0) 508 { 509 swap(j, (j+1)); 510 swapped = true; 511 512 Object tmpId = new Object (); 513 tmpId = indexes[j]; 514 indexes[j] = indexes[j + 1]; 515 indexes[j + 1] = tmpId; 516 } 517 } 518 519 else if(rowData[j][column] instanceof Date) 520 { 521 DateFormat df = DateFormat.getInstance(); 522 df.setLenient(true); 523 524 Date d1 = (Date)rowData[j][column]; 525 Date d2 = (Date)rowData[j + 1][column]; 526 527 if(d1.before(d2)) 528 { 529 swap(j, (j+1)); 530 swapped = true; 531 532 Object tmpId = new Object (); 533 tmpId = indexes[j]; 534 indexes[j] = indexes[j + 1]; 535 indexes[j + 1] = tmpId; 536 } 537 } 538 } 539 540 if(!swapped) 541 return; 542 543 else 544 swapped = false; 545 546 for(j = limit; --j >= st;) 547 { 548 if(rowData[j][column] instanceof String ) 549 { 550 String s1 = (String )rowData[j][column]; 551 String s2 = (String )rowData[j + 1][column]; 552 553 if(s1.compareTo(s2) < 0) 554 { 555 swap(j, (j+1)); 556 swapped = true; 557 558 Object tmpId = new Object (); 559 tmpId = indexes[j]; 560 indexes[j] = indexes[j + 1]; 561 indexes[j + 1] = tmpId; 562 } 563 } 564 565 else if(rowData[j][column] instanceof Date) 566 { 567 DateFormat df = DateFormat.getInstance(); 568 df.setLenient(true); 569 570 Date d1 = (Date)rowData[j][column]; 571 Date d2 = (Date)rowData[j + 1][column]; 572 573 if(d1.before(d2)) 574 { 575 swap(j, (j+1)); 576 swapped = true; 577 578 Object tmpId = new Object (); 579 tmpId = indexes[j]; 580 indexes[j] = indexes[j + 1]; 581 indexes[j + 1] = tmpId; 582 } 583 } 584 } 585 586 if(!swapped) 587 return; 588 } 589 } 590 } 591 592 catch(Exception e) 593 { 594 e.printStackTrace(); 595 } 596 } 597 598 602 private void swap(int j, int k) 603 { 604 int size = columnsNames.length; 605 606 Object T[] = new Object [size]; 607 608 for(int i = 0; i < size; i++) 609 T[i] = rowData[j][i]; 610 611 for(int i = 0; i < size; i++) 612 rowData[j][i] = rowData[k][i]; 613 614 for(int i = 0; i < size; i++) 615 rowData[k][i] = T[i]; 616 } 617 618 619 private final class SortableTableListener extends MouseAdapter 620 { 621 622 private JTable tableView; 623 624 627 protected SortableTableListener(JTable table) 628 { 629 tableView = table; 630 } 631 632 635 public final void mouseClicked(MouseEvent e) 636 { 637 TableColumnModel columnModel = tableView.getColumnModel(); 638 int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 639 int column = tableView.convertColumnIndexToModel(viewColumn); 640 641 if(e.getClickCount() == 1 && column != -1) 642 { 643 int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK; 644 645 if(shiftPressed == 0) 646 ascending = true; 647 648 else 649 ascending = false; 650 651 sortByColumn(column, ascending); 652 dataSort(column, ascending); 653 tableView.setModel(dataModel); 654 setData(rowData, columnsNames); 655 } 656 } 657 } 658 } 659 | Popular Tags |