| 1 7 8 package org.jdesktop.swing; 9 10 import java.awt.Color ; 11 import java.awt.Component ; 12 import java.awt.Dimension ; 13 import java.awt.Font ; 14 import java.awt.Graphics ; 15 import java.awt.event.ActionEvent ; 16 import java.net.MalformedURLException ; 17 import java.net.URL ; 18 import java.util.ArrayList ; 19 import java.util.Date ; 20 import java.util.List ; 21 import java.util.regex.Pattern ; 22 23 import javax.swing.AbstractAction ; 24 import javax.swing.AbstractButton ; 25 import javax.swing.Action ; 26 import javax.swing.Icon ; 27 import javax.swing.JComponent ; 28 import javax.swing.JFrame ; 29 import javax.swing.JLabel ; 30 import javax.swing.JTable ; 31 import javax.swing.KeyStroke ; 32 import javax.swing.SwingUtilities ; 33 import javax.swing.table.AbstractTableModel ; 34 import javax.swing.table.DefaultTableModel ; 35 import javax.swing.table.TableCellRenderer ; 36 import javax.swing.table.TableColumn ; 37 import javax.swing.table.TableModel ; 38 39 import org.jdesktop.swing.data.DataLoader; 40 import org.jdesktop.swing.data.DefaultTableModelExt; 41 import org.jdesktop.swing.data.Link; 42 import org.jdesktop.swing.data.TableModelExtTextLoader; 43 import org.jdesktop.swing.decorator.AlternateRowHighlighter; 44 import org.jdesktop.swing.decorator.ComponentAdapter; 45 import org.jdesktop.swing.decorator.Filter; 46 import org.jdesktop.swing.decorator.FilterPipeline; 47 import org.jdesktop.swing.decorator.Highlighter; 48 import org.jdesktop.swing.decorator.HighlighterPipeline; 49 import org.jdesktop.swing.decorator.PatternFilter; 50 import org.jdesktop.swing.decorator.PatternHighlighter; 51 import org.jdesktop.swing.decorator.PipelineListener; 52 import org.jdesktop.swing.decorator.ShuttleSorter; 53 import org.jdesktop.swing.table.ColumnHeaderRenderer; 54 import org.jdesktop.swing.table.TableColumnExt; 55 import org.jdesktop.swing.util.AncientSwingTeam; 56 57 import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; 58 59 public class JXTableUnitTest extends InteractiveTestCase { 60 61 private DynamicTableModel tableModel = null; 62 private TableModel sortableTableModel; 63 64 public JXTableUnitTest() { 65 super("JXTable unit test"); 66 } 67 68 protected void setUp() throws Exception { 69 super.setUp(); 70 System.setProperty(DataLoader.READER_PRIORITY_KEY, 72 String.valueOf(Thread.NORM_PRIORITY)); 73 if (tableModel == null) { 74 tableModel = new DynamicTableModel(); 75 } 76 sortableTableModel = new AncientSwingTeam(); 77 } 78 79 protected void tearDown() throws Exception { 80 System.getProperties().remove(DataLoader.READER_PRIORITY_KEY); 82 super.tearDown(); 83 } 84 85 86 91 public void testRegisterUniquePipelineListener() { 92 JXTable table = new JXTable(); 93 PatternFilter noFilter = new PatternFilter(".*", 0, 1); 94 table.setFilters(new FilterPipeline(new Filter[] {noFilter})); 95 int listenerCount = table.getFilters().getPipelineListeners().length; 96 PipelineListener l = table.getFilters().getPipelineListeners()[listenerCount - 1]; 97 assertEquals(1, listenerCount); 99 assertEquals(table, l); 100 table.setModel(createModel(0, 20)); 101 assertEquals("pipeline listener count must not change after setModel", listenerCount, table.getFilters().getPipelineListeners().length); 102 103 } 104 108 public void testLeadFocusCell() { 109 final JXTable table = new JXTable(); 110 table.setModel(createModel(0, 10)); 111 table.addRowSelectionInterval(table.getRowCount() - 2, table.getRowCount() - 1); 115 final int leadRow = table.getSelectionModel().getLeadSelectionIndex(); 116 int anchorRow = table.getSelectionModel().getAnchorSelectionIndex(); 117 table.addColumnSelectionInterval(0, 0); 118 final int leadColumn = table.getColumnModel().getSelectionModel().getLeadSelectionIndex(); 119 int anchorColumn = table.getColumnModel().getSelectionModel().getAnchorSelectionIndex(); 120 assertEquals("lead must be last row", table.getRowCount() - 1, leadRow); 121 assertEquals("anchor must be second last row", table.getRowCount() - 2, anchorRow); 122 assertEquals("lead must be first column", 0, leadColumn); 123 assertEquals("anchor must be first column", 0, anchorColumn); 124 final JFrame frame = new JFrame (); 125 frame.add(table); 126 frame.pack(); 127 frame.setVisible(true); 128 table.requestFocus(); 129 SwingUtilities.invokeLater(new Runnable () { 130 public void run() { 131 ComponentAdapter adapter = table.getComponentAdapter(); 132 adapter.row = leadRow; 133 adapter.column = leadColumn; 134 assertTrue("adapter must have focus for leadRow/Column: " + adapter.row + "/" + adapter.column, 136 adapter.hasFocus()); 137 frame.dispose(); 138 139 } 140 }); 141 } 142 143 144 150 public void testSelectionAndToggleModel() { 151 JXTable table = new JXTable(); 152 table.setModel(createModel(0, 10)); 153 table.setSorter(0); 155 table.addRowSelectionInterval(table.getRowCount() - 2, table.getRowCount() - 1); 157 table.setSorter(0); 159 table.setModel(createModel(0, 8)); 161 162 } 163 164 169 public void testSelectionAndAddRows() { 170 JXTable table = new JXTable(); 171 DefaultTableModel model = createModel(0, 10); 172 table.setModel(model); 173 table.setSorter(0); 175 table.addRowSelectionInterval(table.getRowCount() - 2, table.getRowCount() - 1); 177 table.setSorter(0); 179 180 Integer highestValue = new Integer (100); 181 model.addRow(new Object [] { highestValue }); 182 assertEquals(highestValue, table.getValueAt(0, 0)); 183 } 184 185 190 public void testSelectionAndRemoveRows() { 191 JXTable table = new JXTable(); 192 DefaultTableModel model = createModel(0, 10); 193 table.setModel(model); 194 table.setSorter(0); 196 table.addRowSelectionInterval(table.getRowCount() - 2, table.getRowCount() - 1); 198 table.setSorter(0); 200 model.removeRow(0); 201 } 202 203 private DefaultTableModel createModel(int startRow, int count) { 204 DefaultTableModel model = new DefaultTableModel (count, 5); 205 for (int i = 0; i < model.getRowCount(); i++) { 206 model.setValueAt(new Integer (startRow++), i, 0); 207 } 208 return model; 209 } 210 211 212 216 public void testSortedEditability() { 217 int rows = 2; 218 RowObjectTableModel model = createRowObjectTableModel(rows); 219 JXTable table = new JXTable(model); 220 RowObject firstInModel = model.getRowObject(0); 221 assertEquals("rowObject data must be equal", firstInModel.getData1(), table.getValueAt(0, 0)); 222 assertEquals("rowObject editability must be equal", firstInModel.isEditable(), table.isCellEditable(0, 0)); 223 table.setSorter(0); 225 Object firstDataValueInTable = table.getValueAt(0,0); 226 boolean firstEditableValueInTable = table.isCellEditable(0, 0); 227 assertEquals("rowObject data must be equal", firstInModel.getData1(), table.getValueAt(0, 0)); 228 assertEquals("rowObject editability must be equal", firstInModel.isEditable(), table.isCellEditable(0, 0)); 229 assertTrue("lastValue different from first", firstDataValueInTable != 231 table.getValueAt(rows - 1, 0)); 232 assertTrue("lastEditability different from first", firstEditableValueInTable != 233 table.isCellEditable(rows - 1, 0)); 234 table.setSorter(0); 236 assertEquals("last row data must be equal to former first", firstDataValueInTable, 237 table.getValueAt(rows - 1, 0)); 238 assertEquals("last row editability must be equal to former first", firstEditableValueInTable, 239 table.isCellEditable(rows - 1, 0)); 240 } 241 242 246 public void testFilteredEditability() { 247 int rows = 2; 248 RowObjectTableModel model = createRowObjectTableModel(rows); 249 JXTable table = new JXTable(model); 250 for (int i = 0; i < table.getRowCount(); i++) { 252 assertEquals("even/uneven rows must be editable/notEditable " + i, 253 i % 2 == 0, table.isCellEditable(i, 0)); 254 } 255 PatternFilter filter = new PatternFilter("NOT.*", 0, 1); 258 PatternFilter noFilter = new PatternFilter(".*", 0, 1); 259 260 table.setFilters(new FilterPipeline(new Filter[] {noFilter, filter})); 261 assertEquals("row count is half", rows / 2, table.getRowCount()); 262 for (int i = 0; i < table.getRowCount(); i++) { 263 assertFalse("all rows must be not-editable " + i, table.isCellEditable(i, 0)); 264 265 } 266 } 267 268 270 276 private RowObjectTableModel createRowObjectTableModel(int rows) { 277 List rowObjects = new ArrayList (); 278 for (int i = 0; i < rows; i++) { 279 rowObjects.add(new RowObject("somedata" + i, i % 2 == 0)); 280 } 281 return new RowObjectTableModel(rowObjects); 282 } 283 284 287 static class RowObject { 288 289 private String data1; 290 private boolean editable; 291 292 public RowObject(String data1, boolean editable) { 293 this.data1 = data1; 294 this.editable = editable; 295 } 296 297 public String getData1() { 298 return data1; 299 } 300 301 public boolean isEditable() { 302 return editable; 303 } 304 305 } 306 307 310 static class RowObjectTableModel extends AbstractTableModel { 311 312 List data; 313 314 public RowObjectTableModel(List data) { 315 this.data = data; 316 } 317 318 public RowObject getRowObject(int row) { 319 return (RowObject) data.get(row); 320 } 321 public int getColumnCount() { 322 return 2; 323 } 324 325 public int getRowCount() { 326 return data.size(); 327 } 328 329 public Object getValueAt(int row, int col) { 330 RowObject object = getRowObject(row); 331 switch (col) { 332 case 0 : 333 return object.getData1(); 334 case 1 : 335 return object.isEditable() ? "EDITABLE" : "NOT EDITABLE"; 336 default : 337 return null; 338 } 339 } 340 341 public boolean isCellEditable(int row, int col) { 342 return getRowObject(row).isEditable(); 343 } 344 } 345 346 347 public void testLinkCellType() { 348 JXTable table = new JXTable(tableModel); 349 350 assertEquals(Link.class, 351 table.getColumnClass(DynamicTableModel.IDX_COL_LINK)); 352 353 TableCellRenderer renderer = table.getCellRenderer(0, 354 DynamicTableModel.IDX_COL_LINK); 355 356 } 360 361 366 public void testToggleFiltersWhileSorting() { 367 Object [][] rowData = new Object [][] { 368 new Object [] { Boolean.TRUE, "AA" }, 369 new Object [] { Boolean.FALSE, "AB" }, 370 new Object [] { Boolean.FALSE, "AC" }, 371 new Object [] { Boolean.TRUE, "BA" }, 372 new Object [] { Boolean.FALSE, "BB" }, 373 new Object [] { Boolean.TRUE, "BC" } }; 374 String [] columnNames = new String [] { "Critical", "Task" }; 375 final JXTable table = new JXTable(rowData, columnNames); 376 Filter filterA = new PatternFilter("A.*", Pattern.CASE_INSENSITIVE, 1); 377 table.setFilters(new FilterPipeline(new Filter[] {filterA})); 381 table.setSorter(1); 382 Filter filterB = new PatternFilter(".*", Pattern.CASE_INSENSITIVE, 1); 383 table.setFilters(new FilterPipeline(new Filter[] {filterB})); 384 table.setSorter(1); 385 } 386 387 393 public void testToggleFiltersWhileSortingLonger() { 394 Object [][] rowData = new Object [][] { 395 new Object [] { Boolean.TRUE, "AA" }, 396 new Object [] { Boolean.FALSE, "AB" }, 397 new Object [] { Boolean.FALSE, "AC" }, 398 new Object [] { Boolean.TRUE, "BA" }, 399 new Object [] { Boolean.FALSE, "BB" }, 400 new Object [] { Boolean.TRUE, "BC" } }; 401 String [] columnNames = new String [] { "Critical", "Task" }; 402 final JXTable table = new JXTable(rowData, columnNames); 403 table.setFilters(createFilterPipeline(false, 1)); 407 table.setSorter(0); 408 table.setSorter(1); 409 table.setFilters(createFilterPipeline(true, 1)); 410 table.setFilters(createFilterPipeline(false, 1)); 411 table.setSorter(0); 412 } 413 414 private FilterPipeline createFilterPipeline(boolean matchAll, int col) { 415 Filter filter; 416 if (matchAll) { 417 filter = new PatternFilter(".*", Pattern.CASE_INSENSITIVE, col); 418 } else { 419 filter = new PatternFilter("A.*", Pattern.CASE_INSENSITIVE, col); 420 } 421 return new FilterPipeline(new Filter[] {filter}); 422 423 } 424 433 public void testRemoveFilterWhileSorting() { 434 Object [][] rowData = new Object [][] { 435 new Object [] { Boolean.TRUE, "AA" }, 436 new Object [] { Boolean.FALSE, "AB" }, 437 new Object [] { Boolean.FALSE, "AC" }, 438 new Object [] { Boolean.TRUE, "BA" }, 439 new Object [] { Boolean.FALSE, "BB" }, 440 new Object [] { Boolean.TRUE, "BC" } }; 441 String [] columnNames = new String [] { "Critical", "Task" }; 442 final JXTable table = new JXTable(rowData, columnNames); 443 int rows = table.getRowCount(); 444 Filter filterA = new PatternFilter("A.*", Pattern.CASE_INSENSITIVE, 1); 445 table.setFilters(new FilterPipeline(new Filter[] {filterA})); 446 table.setSorter(1); 447 table.setFilters(null); 448 assertEquals("rowCount must be original", rows, table.getRowCount()); 449 table.getValueAt(rows - 1, 0); 450 451 452 } 453 454 462 public void testLazyRenderersByClass() { 463 JXTable table = new JXTable(); 464 assertEquals("default Boolean renderer", JXTable.BooleanRenderer.class, table.getDefaultRenderer(Boolean .class).getClass()); 465 assertEquals("default Number renderer", JXTable.NumberRenderer.class, table.getDefaultRenderer(Number .class).getClass()); 466 assertEquals("default Double renderer", JXTable.DoubleRenderer.class, table.getDefaultRenderer(Double .class).getClass()); 467 assertEquals("default Date renderer", JXTable.DateRenderer.class, table.getDefaultRenderer(Date .class).getClass()); 468 assertEquals("default Link renderer", JXTable.LinkRenderer.class, table.getDefaultRenderer(Link.class).getClass()); 469 assertEquals("default Icon renderer", JXTable.IconRenderer.class, table.getDefaultRenderer(Icon .class).getClass()); 470 } 471 472 476 public void testTableColumnsWithFilters() { 477 JXTable table = new JXTable(tableModel); 478 assertEquals("table columns are equal to columns of model", 479 tableModel.getColumnCount(), table.getColumnCount()); 480 TableColumn column = table.getColumnExt(0); 481 table.removeColumn(column); 482 int columnCountAfterRemove = table.getColumnCount(); 483 assertEquals("table columns must be one less than columns of model", 484 tableModel.getColumnCount() - 1, columnCountAfterRemove); 485 table.setFilters(new FilterPipeline(new Filter[] { 486 new ShuttleSorter(1, false), })); 488 assertEquals("table columns must be unchanged after setting filter", 489 columnCountAfterRemove, table.getColumnCount()); 490 491 } 492 493 public void testDynamicColumns() { 494 URL url = JXTableUnitTest.class.getResource("resources/bugdata.txt"); 495 DefaultTableModelExt data = new DefaultTableModelExt(url); 496 System.out.println("loader prio" + System.getProperty(DataLoader.READER_PRIORITY_KEY)); 497 JXTable table = new JXTable(data); 498 try { 499 data.startLoading(); 500 } 501 catch (Exception ex) { 502 fail("Exception in data load: " + ex.getMessage()); 503 } 504 505 while(data.isLoading()); 507 508 assertEquals(8, data.getColumnCount()); 509 assertEquals(8, table.getColumnCount()); 510 } 511 512 public void interactiveTestTableLoading() { 513 URL url = JXTableUnitTest.class.getResource("resources/stringdata.csv"); 514 System.out.println("url="+url); 515 DefaultTableModelExt data = new DefaultTableModelExt(url); 516 TableModelExtTextLoader loader = (TableModelExtTextLoader)data.getLoader(); 517 loader.setFirstRowHeader(true); 518 loader.setColumnDelimiter(","); 519 JXTable table = new JXTable(data); 520 try { 521 data.startLoading(); 522 } 523 catch (Exception ex) { 524 fail("Exception in data load: " + ex.getMessage()); 525 } 526 JFrame frame = wrapWithScrollingInFrame(table, "TableLoading Test"); 527 frame.setVisible(true); } 529 530 public void interactiveTestLinkCell() { 531 JXTable table = new JXTable(tableModel); 532 JFrame frame = wrapWithScrollingInFrame(table, "TableLinkCell Test"); 533 frame.setVisible(true); } 535 536 public void interactiveTestToggleSortingEnabled() { 537 URL url = JXTableUnitTest.class.getResource("resources/stringdata.csv"); 539 System.out.println("url="+url); 540 DefaultTableModelExt data = new DefaultTableModelExt(url); 541 TableModelExtTextLoader loader = (TableModelExtTextLoader)data.getLoader(); 542 loader.setFirstRowHeader(true); 543 loader.setColumnDelimiter(","); 544 final JXTable table = new JXTable(data); 545 try { 546 data.startLoading(); 547 } 548 catch (Exception ex) { 549 fail("Exception in data load: " + ex.getMessage()); 550 } 551 Action toggleSortableAction = new AbstractAction ("Toggle Sortable") { 552 553 public void actionPerformed(ActionEvent e) { 554 table.setSortable(!table.isSortable()); 555 556 } 557 558 }; 559 table.getActionMap().put("toggleSortable", toggleSortableAction); 560 table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( 561 KeyStroke.getKeyStroke("F6"), "toggleSortable"); 562 JFrame frame = wrapWithScrollingInFrame(table, "ToggleSortingEnabled Test (press F6 to toggle)"); 563 frame.setVisible(true); 565 } 566 public void interactiveTestTableSizing1() { 567 JXTable table = new JXTable(); 568 table.setAutoCreateColumnsFromModel(false); 569 table.setModel(tableModel); 570 571 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 572 573 TableColumnExt columns[] = new TableColumnExt[tableModel.getColumnCount()]; 574 for (int i = 0; i < columns.length; i++) { 575 columns[i] = new TableColumnExt(i); 576 table.addColumn(columns[i]); 577 } 578 columns[0].setPrototypeValue(new Integer (0)); 579 columns[1].setPrototypeValue("Simple String Value"); 580 columns[2].setPrototypeValue(new Integer (1000)); 581 columns[3].setPrototypeValue(Boolean.TRUE); 582 columns[4].setPrototypeValue(new Date (100)); 583 columns[5].setPrototypeValue(new Float (1.5)); 584 columns[6].setPrototypeValue(new Link("Sun Micro", "_blank", 585 tableModel.linkURL)); 586 columns[7].setPrototypeValue(new Integer (3023)); 587 columns[8].setPrototypeValue("John Doh"); 588 columns[9].setPrototypeValue("23434 Testcase St"); 589 columns[10].setPrototypeValue(new Integer (33333)); 590 columns[11].setPrototypeValue(Boolean.FALSE); 591 592 table.setVisibleRowCount(12); 593 594 JFrame frame = wrapWithScrollingInFrame(table, "TableSizing1 Test"); 595 frame.setVisible(true); 596 } 597 598 public void interactiveTestTableSizing2() { 599 JXTable table = new JXTable(); 600 table.setAutoCreateColumnsFromModel(false); 601 table.setModel(tableModel); 602 603 TableColumnExt columns[] = new TableColumnExt[6]; 604 int viewIndex = 0; 605 for (int i = columns.length - 1; i >= 0; i--) { 606 columns[viewIndex] = new TableColumnExt(i); 607 table.addColumn(columns[viewIndex++]); 608 } 609 columns[5].setHeaderValue("String Value"); 610 columns[5].setPrototypeValue("9999"); 611 columns[4].setHeaderValue("String Value"); 612 columns[4].setPrototypeValue("Simple String Value"); 613 columns[3].setHeaderValue("Int Value"); 614 columns[3].setPrototypeValue(new Integer (1000)); 615 columns[2].setHeaderValue("Bool"); 616 columns[2].setPrototypeValue(Boolean.FALSE); 617 columns[1].setHeaderValue("Date"); 619 columns[1].setPrototypeValue(new Date (0)); 620 columns[0].setHeaderValue("Float"); 622 columns[0].setPrototypeValue(new Float (5.5)); 623 624 table.setRowHeight(24); 625 table.setRowMargin(2); 626 JFrame frame = wrapWithScrollingInFrame(table, "TableSizing2 Test"); 627 frame.setVisible(true); 628 } 629 630 public void interactiveTestTableAlternateHighlighter1() { 631 JXTable table = new JXTable(tableModel); 632 table.setRowHeight(22); 633 table.setRowMargin(1); 634 635 table.setFilters(new FilterPipeline(new Filter[] { 636 new ShuttleSorter(0, true) })); 638 639 table.setHighlighters(new HighlighterPipeline(new Highlighter[] { 640 AlternateRowHighlighter. 641 linePrinter, 642 })); 643 644 JFrame frame = wrapWithScrollingInFrame(table, "TableAlternateRowHighlighter1 Test"); 645 frame.setVisible(true); 646 } 647 648 public void interactiveTestTableAlternateRowHighlighter2() { 649 JXTable table = new JXTable(tableModel); 650 table.setRowHeight(22); 651 table.setRowMargin(1); 652 table.setFilters(new FilterPipeline(new Filter[] { 653 new ShuttleSorter(1, false), })); 655 656 table.setHighlighters(new HighlighterPipeline(new Highlighter[] { 657 AlternateRowHighlighter.classicLinePrinter, 658 })); 659 660 JFrame frame = wrapWithScrollingInFrame(table, "TableAlternateRowHighlighter2 Test"); 661 frame.setVisible(true); 662 } 663 664 public void interactiveTestTableSorter1() { 665 JXTable table = new JXTable(sortableTableModel); 666 table.setHighlighters(new HighlighterPipeline(new Highlighter[] { 667 AlternateRowHighlighter.notePadBackground, 668 })); 669 table.setBackground(new Color (0xFF, 0xFF, 0xCC)); table.setGridColor(Color.cyan.darker()); 671 table.setRowHeight(22); 672 table.setRowMargin(1); 673 table.setShowHorizontalLines(true); 674 table.setFilters(new FilterPipeline(new Filter[] { 675 new ShuttleSorter(0, true), new ShuttleSorter(1, true), })); 678 679 JFrame frame = wrapWithScrollingInFrame(table, "TableSorter1 col 0= asc, col 1 = asc"); 680 frame.setVisible(true); 681 682 } 683 684 public void interactiveTestTableSorter2() { 685 JXTable table = new JXTable(sortableTableModel); 686 table.setBackground(new Color (0xF5, 0xFF, 0xF5)); table.setGridColor(Color.cyan.darker()); 688 table.setRowHeight(22); 689 table.setRowMargin(1); 690 table.setShowHorizontalLine
|