1 7 8 package org.jdesktop.swing; 9 10 import java.text.MessageFormat ; 11 import java.util.ArrayList ; 12 import java.util.Date ; 13 import java.util.Enumeration ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Hashtable ; 17 import java.util.Timer ; 18 import java.util.TimerTask ; 19 import java.util.Vector ; 20 import java.util.regex.Pattern ; 21 import javax.print.attribute.HashPrintRequestAttributeSet ; 22 import javax.print.attribute.PrintRequestAttributeSet ; 23 24 import java.awt.Color ; 25 import java.awt.Component ; 26 import java.awt.Dimension ; 27 import java.awt.EventQueue ; 28 import java.awt.FontMetrics ; 29 import java.awt.Graphics ; 30 import java.awt.Point ; 31 import java.awt.Rectangle ; 32 import java.awt.event.*; 33 import java.awt.print.Printable ; 34 import java.awt.print.PrinterException ; 35 import java.awt.print.PrinterJob ; 36 37 import java.text.DateFormat ; 38 import java.text.NumberFormat ; 39 40 import javax.swing.ActionMap ; 41 import javax.swing.Icon ; 42 import javax.swing.ImageIcon ; 43 import javax.swing.JCheckBox ; 44 import javax.swing.JLabel ; 45 import javax.swing.JTable ; 46 import javax.swing.JViewport ; 47 import javax.swing.ListSelectionModel ; 48 import javax.swing.UIDefaults ; 49 import javax.swing.event.TableModelEvent ; 50 import javax.swing.table.DefaultTableCellRenderer ; 51 import javax.swing.table.JTableHeader ; 52 import javax.swing.table.TableCellRenderer ; 53 import javax.swing.table.TableColumn ; 54 import javax.swing.table.TableColumnModel ; 55 import javax.swing.table.TableModel ; 56 57 import org.jdesktop.swing.data.Link; 58 import org.jdesktop.swing.data.MetaData; 59 import org.jdesktop.swing.data.MetaDataProvider; 60 import org.jdesktop.swing.data.DefaultTableModelExt; 61 62 import org.jdesktop.swing.table.ColumnHeaderRenderer; 63 import org.jdesktop.swing.table.TableColumnExt; 64 import org.jdesktop.swing.table.TableColumnModelExt; 65 66 import org.jdesktop.swing.decorator.ComponentAdapter; 67 import org.jdesktop.swing.decorator.FilterPipeline; 68 import org.jdesktop.swing.decorator.HighlighterPipeline; 69 import org.jdesktop.swing.decorator.PipelineEvent; 70 import org.jdesktop.swing.decorator.PipelineListener; 71 import org.jdesktop.swing.decorator.Sorter; 72 import org.jdesktop.swing.table.DefaultTableColumnModelExt; 73 74 81 public class JXTable extends JTable implements PipelineListener, Searchable { 82 83 public static boolean TRACE = false; 84 88 public static final int PRINT_MODE_NORMAL = 0; 89 90 95 public static final int PRINT_MODE_FIT_WIDTH = 1; 96 97 protected Sorter sorter = null; 98 protected FilterPipeline filters = null; 99 protected HighlighterPipeline highlighters = null; 100 101 private final ComponentAdapter dataAdapter = new TableAdapter(this); 103 104 private final static MouseAdapter headerListener = new MouseAdapter() { 106 public void mouseClicked(MouseEvent e) { 108 JTableHeader header = (JTableHeader ) e.getSource(); 109 JXTable table = (JXTable) header.getTable(); 110 if (!table.isSortable()) return; 111 if ((e.getModifiersEx() & e.SHIFT_DOWN_MASK) == e.SHIFT_DOWN_MASK) { 112 table.resetSorter(); 113 } 114 else { 115 116 int column = header.getColumnModel().getColumnIndexAtX(e.getX()); 117 if (column >= 0) { 118 table.setSorter(column); 119 } 120 } 121 header.repaint(); 122 } 123 }; 124 125 130 private transient boolean isPrinting = false; 131 132 private boolean sortable = false; 133 private int visibleRowCount = 18; 134 135 public JXTable() { 136 init(); 137 } 138 139 public JXTable(TableModel dm) { 140 super(dm); 141 init(); 142 } 143 144 public JXTable(TableModel dm, TableColumnModel cm) { 145 super(dm, cm); 146 init(); 147 } 148 149 public JXTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) { 150 super(dm, cm, sm); 151 init(); 152 } 153 154 public JXTable(int numRows, int numColumns) { 155 super(numRows, numColumns); 156 init(); 157 } 158 159 public JXTable(Vector rowData, Vector columnNames) { 160 super(rowData, columnNames); 161 init(); 162 } 163 164 public JXTable(Object [][] rowData, Object [] columnNames) { 165 super(rowData, columnNames); 166 init(); 167 } 168 169 protected void init() { 170 setSortable(true); 171 ActionMap map = getActionMap(); 173 map.put("print", new Actions("print")); 174 map.put("find", new Actions("find")); 175 176 LinkHandler handler = new LinkHandler(); 180 addMouseListener(handler); 181 addMouseMotionListener(handler); 182 } 183 184 185 194 public TableCellRenderer getNewDefaultRenderer(Class columnClass) { 195 TableCellRenderer renderer = getDefaultRenderer(columnClass); 196 if (renderer != null) { 197 try { 198 return (TableCellRenderer ) renderer.getClass().newInstance(); 199 } catch (Exception e) { 200 e.printStackTrace(); 201 } 202 } 203 return null; 204 } 205 206 private void setLazyValue(Hashtable h, Class c, String s) { 207 h.put(c, new UIDefaults.ProxyLazyValue (s)); 208 } 209 210 private void setLazyRenderer(Class c, String s) { 211 setLazyValue(defaultRenderersByColumnClass, c, s); 212 } 213 214 219 protected void createDefaultRenderers() { 220 226 defaultRenderersByColumnClass = new UIDefaults (); 227 228 setLazyRenderer(Object .class, 230 "javax.swing.table.DefaultTableCellRenderer"); 231 232 setLazyRenderer(Number .class, "org.jdesktop.swing.JXTable$NumberRenderer"); 234 235 setLazyRenderer(Float .class, "org.jdesktop.swing.JXTable$DoubleRenderer"); 237 setLazyRenderer(Double .class, "org.jdesktop.swing.JXTable$DoubleRenderer"); 238 239 setLazyRenderer(Date .class, "org.jdesktop.swing.JXTable$DateRenderer"); 241 242 setLazyRenderer(Icon .class, "org.jdesktop.swing.JXTable$IconRenderer"); 244 setLazyRenderer(ImageIcon .class, "org.jdesktop.swing.JXTable$IconRenderer"); 245 246 setLazyRenderer(Boolean .class, "org.jdesktop.swing.JXTable$BooleanRenderer"); 248 249 setLazyRenderer(Link.class, "org.jdesktop.swing.JXTable$LinkRenderer"); 251 } 252 253 254 258 private class Actions extends UIAction { 259 Actions(String name) { 260 super(name); 261 } 262 263 public void actionPerformed(ActionEvent evt) { 264 if ("print".equals(getName())) { 265 try { 266 print(); 267 } 268 catch (PrinterException ex) { 269 ex.printStackTrace(); 271 } 272 } 273 else if ("find".equals(getName())) { 274 find(); 275 } 276 } 277 } 278 279 private JXFindDialog dialog = null; 280 private boolean automaticSortDisabled; 281 282 private void find() { 283 if (dialog == null) { 284 dialog = new JXFindDialog(this); 285 } 286 dialog.setVisible(true); 287 } 288 289 301 public void setSortable(boolean sortable) { 302 if (sortable == isSortable()) return; 303 this.sortable = sortable; 304 firePropertyChange("sortable", !sortable, sortable); 305 if (sorter != null) { 307 contentsChanged(null); 308 } 309 310 } 311 312 public boolean isSortable() { 313 return sortable; 314 } 315 316 317 326 public void tableChanged(TableModelEvent e) { 327 Selection selection = new Selection(this); 328 if (filters != null) { 329 filters.flush(); } 331 else if (sorter != null) { 332 sorter.refresh(); 333 } 337 338 super.tableChanged(e); 339 restoreSelection(selection); 340 } 341 342 public void contentsChanged(PipelineEvent e) { 343 removeSorter(); 344 clearSelection(); 345 346 setRowHeight(getRowHeight()); 349 revalidate(); 350 repaint(); 351 } 352 353 public int getRowCount() { 354 int count; 355 if (filters == null) { 356 count = getModel().getRowCount(); 357 } 358 else { 359 count = filters.getOutputSize(); 360 } 361 return count; 362 } 363 364 371 public int convertRowIndexToModel(int row) { 372 if (sorter == null) { 373 if (filters == null) { 374 return row; 375 } 376 else { 377 return filters.convertRowIndexToModel(row); 379 } 380 } 381 else { 382 return sorter.convertRowIndexToModel(row); 385 } 386 } 387 388 395 public int convertRowIndexToView(int row) { 396 if (sorter == null) { 397 if (filters == null) { 398 return row; 399 } 400 else { 401 return filters.convertRowIndexToView(row); 403 } 404 } 405 else { 406 return sorter.convertRowIndexToView(row); 409 } 410 } 411 412 415 public Object getValueAt(int row, int column) { 416 if (sorter == null) { if (filters == null) { return super.getValueAt(row, column); } 420 else { return filters.getValueAt(row, convertColumnIndexToModel(column)); 422 } 423 } 424 else { return sorter.getValueAt(row, convertColumnIndexToModel(column)); 426 } 427 } 428 429 public void setValueAt(Object aValue, int row, int column) { 430 if (sorter == null) { 431 if (filters == null) { 432 super.setValueAt(aValue, row, column); 433 } 434 else { 435 filters.setValueAt(aValue, row, convertColumnIndexToModel(column)); 436 } 437 } 438 else { 439 sorter.setValueAt(aValue, row, convertColumnIndexToModel(column)); 440 } 441 } 442 443 public boolean isCellEditable(int row, int column) { 444 if (sorter == null) { 445 if (filters == null) { 446 return super.isCellEditable(row, column); 447 } 448 else { 449 return filters.isCellEditable(row, convertColumnIndexToModel(column)); 450 } 451 } 452 else { 453 return sorter.isCellEditable(row, convertColumnIndexToModel(column)); 454 } 455 } 456 457 public void setModel(TableModel newModel) { 458 clearSelection(); 462 super.setModel(newModel); 463 use(filters); 464 } 465 466 467 473 public void setTableHeader(JTableHeader tableHeader) { 474 if (tableHeader != null) { 476 tableHeader.addMouseListener(headerListener); 477 tableHeader.setDefaultRenderer(new ColumnHeaderRenderer()); 478 } 479 super.setTableHeader(tableHeader); 480 } 481 482 487 488 protected TableColumnModel createDefaultColumnModel() { 489 return new DefaultTableColumnModelExt(); 490 } 491 492 private void restoreSelection(Selection selection) { 493 clearSelection(); 495 for (int i = 0; i < selection.selected.length; i++) { 496 if ((selection.selected[i] != selection.lead) && (selection.selected[i] < getModel().getRowCount())) { 499 int index = convertRowIndexToView(selection.selected[i]); 500 selectionModel.addSelectionInterval(index, index); 501 } 502 } 503 504 if ((selection.lead >= 0) && (selection.lead < getModel().getRowCount())) { 507 selection.lead = convertRowIndexToView(selection.lead); 508 selectionModel.addSelectionInterval(selection.lead, selection.lead); 509 } 510 } 511 512 public FilterPipeline getFilters() { 513 return filters; 514 } 515 516 521 private void use(FilterPipeline pipeline) { 522 if (pipeline != null) { 523 if (initialUse(pipeline)) { 525 pipeline.addPipelineListener(this); 526 pipeline.assign(getComponentAdapter()); 527 } 528 pipeline.flush(); 529 } 530 } 531 532 537 private boolean initialUse(FilterPipeline pipeline) { 538 PipelineListener[] l = pipeline.getPipelineListeners(); 539 for (int i = 0; i < l.length; i++) { 540 if (this.equals(l[i])) return false; 541 } 542 return true; 543 } 544 545 public void setFilters(FilterPipeline pipeline) { 546 unsetFilters(); 547 doSetFilters(pipeline); 548 } 549 550 private void unsetFilters() { 551 if (filters == null) return; 552 filters.removePipelineListener(this); 554 contentsChanged(null); 557 } 558 559 private void doSetFilters(FilterPipeline pipeline) { 560 filters = pipeline; 561 use(filters); 562 } 563 564 public HighlighterPipeline getHighlighters() { 565 return highlighters; 566 } 567 568 public void setHighlighters(HighlighterPipeline pipeline) { 569 highlighters = pipeline; 570 } 571 572 private void removeSorter() { 573 sorter = null; 579 getTableHeader().repaint(); 580 } 581 582 583 586 protected void resetSorter() { 587 if (sorter != null) { 588 Selection selection = new Selection(this); 589 removeSorter(); 590 restoreSelection(selection); 591 } 592 } 593 594 private Sorter refreshSorter(int columnIndex) { 595 TableColumn col = getColumnModel().getColumn(columnIndex); 596 if (col instanceof TableColumnExt) { 597 TableColumnExt column = (TableColumnExt) col; 598 Sorter newSorter = column.getSorter(); 599 if (newSorter != null) { 600 newSorter.interpose(null, getComponentAdapter(), null); 603 newSorter.interpose(filters, getComponentAdapter(), sorter); return newSorter; 606 } 607 } 608 return sorter; 609 } 610 611 614 protected void setSorter(int columnIndex) { 615 Selection selection = new Selection(this); 616 if (sorter == null) { 617 sorter = refreshSorter(columnIndex); } 619 else { 620 int modelColumnIndex = convertColumnIndexToModel(columnIndex); 621 if (sorter.getColumnIndex() == modelColumnIndex) { 622 sorter.toggle(); 623 } 624 else { 625 sorter = refreshSorter(columnIndex); } 627 } 628 restoreSelection(selection); 629 } 630 631 634 public Sorter getSorter(int columnIndex) { 635 return sorter == null ? null : 636 sorter.getColumnIndex() == convertColumnIndexToModel(columnIndex) ? 637 sorter : null; 638 } 639 640 643 protected void removeColumns() { 644 646 TableColumnModel cm = getColumnModel(); 647 while (cm.getColumnCount() > 0) { 648 cm.removeColumn(cm.getColumn(0)); 649 } 650 } 651 652 public List getColumns() { 653 return null; 654 } 655 656 668 669 public TableColumnExt getColumnExt(Object identifier) { 670 return (TableColumnExt)super.getColumn(identifier); 671 } 672 673 public TableColumnExt getColumnExt(int viewColumnIndex) { 674 return (TableColumnExt) getColumnModel().getColumn(viewColumnIndex); 675 } 676 677 689 713 714 722 protected TableModel createDefaultDataModel() { 723 return new DefaultTableModelExt(); 724 } 725 726 public void createDefaultColumnsFromModel() { 727 TableModel model = getModel(); 728 if (model != null) { 729 int modelColumnCount = model.getColumnCount(); 733 TableColumn newColumns[] = new TableColumn [modelColumnCount]; 734 for (int i = 0; i < newColumns.length; i++) { 735 newColumns[i] = createColumn(i); 736 } 737 738 if (model instanceof MetaDataProvider) { 739 MetaData metaData[] = ((MetaDataProvider)model).getMetaData(); 740 for(int i = 0; i < metaData.length; i++) { 741 newColumns[i].setIdentifier(metaData[i].getName()); 742 newColumns[i].setHeaderValue(metaData[i].getLabel()); 743 } 744 } 745 746 TableColumnModel columnModel = getColumnModel(); 748 while (columnModel.getColumnCount() > 0) { 749 columnModel.removeColumn(columnModel.getColumn(0)); 750 } 751 752 for (int i = 0; i < newColumns.length; i++) { 754 addColumn(newColumns[i]); 755 } 756 } 757 } 758 759 protected TableColumn createColumn(int modelIndex) { 760 return new TableColumnExt(modelIndex); 761 } 762 763 764 769 public int getColumnMargin() { 770 return getColumnModel().getColumnMargin(); 771 } 772 773 778 public void setColumnMargin(int value) { 779 getColumnModel().setColumnMargin(value); 780 } 781 782 787 public int getSelectionMode() { 788 return getSelectionModel().getSelectionMode(); 789 } 790 791 802 public Component prepareRenderer(TableCellRenderer renderer, int row, 803 int column) { 804 Component stamp = super.prepareRenderer(renderer, row, column); 805 if (highlighters == null) { 806 return stamp; } 808 else { 809 ComponentAdapter adapter = getComponentAdapter(); 811 adapter.row = row; 812 adapter.column = column; 813 return highlighters.apply(stamp, adapter); 814 } 815 } 816 817 protected ComponentAdapter getComponentAdapter() { 818 return dataAdapter; 820 } 821 822 public int search(String searchString) { 823 return search(searchString, -1); 824 } 825 826 public int search(String searchString, int columnIndex) { 827 Pattern pattern = null; 828 if (searchString != null) { 829 return search(Pattern.compile(searchString, 0), columnIndex); 830 } 831 return -1; 832 } 833 834 public int search(Pattern pattern) { 835 return search(pattern, -1); 836 } 837 838 public int search(Pattern pattern, int startIndex) { 839 return search(pattern, startIndex, false); 840 } 841 842 private int lastCol = 0; 844 845 849 public int search(Pattern pattern, int startIndex, boolean backwards) { 850 if (pattern == null) { 851 lastCol = 0; 852 return -1; 853 } 854 int rows = getRowCount(); 855 int endCol = getColumnCount(); 856 857 int startRow = startIndex + 1; 858 int matchRow = -1; 859 860 if (backwards == true) { 861 for (int r = startRow; r >= 0 && matchRow == -1; r--) { 862 for (int c = endCol; c >= 0; c--) { 863 Object value = getValueAt(r, c); 864 if ( (value != null) && 865 pattern.matcher(value.toString()).find()) { 866 changeSelection(r, c, false, false); 867 matchRow = r; 868 lastCol = c; 869 break; } 871 } 872 if (matchRow == -1) { 873 lastCol = endCol; 874 } 875 } 876 } 877 else { 878 for (int r = startRow; r < rows && matchRow == -1; r++) { 879 for (int c = lastCol; c < endCol; c++) { 880 Object value = getValueAt(r, c); 881 if ( (value != null) && 882 pattern.matcher(value.toString()).find()) { 883 changeSelection(r, c, false, false); 884 matchRow = r; 885 lastCol = c; 886 break; } 888 } 889 if (matchRow == -1) { 890 lastCol = 0; 891 } 892 } 893 } 894 895 if (matchRow != -1) { 896 Object viewport = getParent(); 897 if (viewport instanceof JViewport ) { 898 Rectangle rect = getCellRect(getSelectedRow(), 0, true); 899 Point pt = ( (JViewport ) viewport).getViewPosition(); 900 rect.setLocation(rect.x - pt.x, rect.y - pt.y); 901 ( (JViewport ) viewport).scrollRectToVisible(rect); 902 } 903 } 904 return matchRow; 905 } 906 907 public void setVisibleRowCount(int visibleRowCount) { 908 this.visibleRowCount = visibleRowCount; 909 } 910 911 public int getVisibleRowCount() { 912 return visibleRowCount; 913 } 914 915 public Dimension getPreferredScrollableViewportSize() { 916 Dimension prefSize = super.getPreferredScrollableViewportSize(); 917 918 922 if (prefSize.getWidth() == 450 && prefSize.getHeight() == 400) { 923 TableColumnModel columnModel = getColumnModel(); 924 int columnCount = columnModel.getColumnCount(); 925 926 int w = 0; 927 for (int i = 0; i < columnCount; i++) { 928 TableColumn column = columnModel.getColumn(i); 929 initializeColumnPreferredWidth(column); 930 w += column.getPreferredWidth(); 931 } 932 prefSize.width = w; 933 JTableHeader header = getTableHeader(); 934 int rowCount = getVisibleRowCount(); 936 prefSize.height = rowCount * getRowHeight() + 937 (header != null? header.getPreferredSize().height : 0); 938 setPreferredScrollableViewportSize(prefSize); 939 } 940 return prefSize; 941 } 942 943 951 protected void initializeColumnPreferredWidth(TableColumn column) { 952 if (column instanceof TableColumnExt) { 953 Dimension cellSpacing = getIntercellSpacing(); 954 TableColumnExt columnx = (TableColumnExt) column; 955 Object prototypeValue = columnx.getPrototypeValue(); 957 if (prototypeValue != null) { 958 TableCellRenderer renderer = getCellRenderer(0, 960 convertColumnIndexToView(columnx.getModelIndex())); 961 Component comp = renderer.getTableCellRendererComponent(this, 962 prototypeValue, false, false, 0, 0); 963 int prefWidth = comp.getPreferredSize().width + cellSpacing.width; 964 965 renderer = columnx.getHeaderRenderer(); 967 if (renderer == null) { 968 JTableHeader header = getTableHeader(); 969 if (header != null) { 970 renderer = header.getDefaultRenderer(); 971 } 972 } 973 if (renderer != null) { 974 comp = renderer.getTableCellRendererComponent(this, 975 columnx.getHeaderValue(), false, false, 0, 976 convertColumnIndexToView(columnx.getModelIndex())); 977 978 prefWidth = Math.max(comp.getPreferredSize().width, prefWidth); 979 } 980 prefWidth += getColumnModel().getColumnMargin(); 981 columnx.setPreferredWidth(prefWidth); 982 } 983 } 987 } 988 989 991 996 public boolean isPrinting() { 997 return isPrinting; 998 } 999 1000 1013 public boolean print() throws PrinterException { 1014 1015 return print(PRINT_MODE_FIT_WIDTH); 1016 } 1017 1018 1035 public boolean print(int printMode) throws PrinterException { 1036 1037 return print(printMode, null, null); 1038 } 1039 1040 1063 public boolean print(int printMode, 1064 MessageFormat headerFormat, 1065 MessageFormat footerFormat) throws PrinterException { 1066 1067 return print(printMode, headerFormat, footerFormat, true, null); 1068 } 1069 1070 1123 public boolean print(int printMode, 1124 MessageFormat headerFormat, 1125 MessageFormat footerFormat, 1126 boolean showPrintDialog, 1127 PrintRequestAttributeSet attr) throws PrinterException { 1128 1129 if (isEditing()) { 1130 if (!getCellEditor().stopCellEditing()) { 1132 getCellEditor().cancelCellEditing(); 1133 } 1134 } 1135 1136 if (attr == null) { 1137 attr = new HashPrintRequestAttributeSet (); 1138 } 1139 final PrintRequestAttributeSet attrset = attr; 1140 1141 final PrinterJob job = PrinterJob.getPrinterJob(); 1142 job.setPrintable(getPrintable(printMode, headerFormat, footerFormat)); 1143 1144 if (showPrintDialog && !job.printDialog(attrset)) { 1145 return false; 1146 } 1147 1148 Timer timer = new Timer (); 1159 TimerTask task = new TimerTask () { 1160 public void run() { 1161 EventQueue.invokeLater(new Runnable () { 1162 public void run() { 1163 isPrinting = true; 1165 try { 1166 job.print(attrset); 1168 } 1169 catch (PrinterException e) { 1170 e.printStackTrace(); 1172 } 1173 finally { 1174 isPrinting = false; 1176 } 1177 } 1178 }); 1179 } 1180 }; 1181 timer.schedule(task, 100); 1182 1183 return true; 1185 } 1186 1187 1314 public Printable getPrintable(int printMode, 1315 MessageFormat headerFormat, 1316 MessageFormat footerFormat) { 1317 1318 return new TablePrintable(this, printMode, headerFormat, footerFormat); 1319 } 1320 1321 static class TableAdapter extends ComponentAdapter { 1322 private final JTable table; 1323 1324 1330 public TableAdapter(JTable component) { 1331 super(component); 1332 table = component; 1333 } 1334 1335 1340 public JTable getTable() { 1341 return table; 1342 } 1343 1344 1347 public boolean hasFocus() { 1348 if (table instanceof JXTable && ( (JXTable) table).isPrinting()) { 1350 return false; 1351 } 1352 boolean rowIsLead = (table.getSelectionModel(). 1353 getLeadSelectionIndex() == row); 1354 boolean colIsLead = 1355 (table.getColumnModel().getSelectionModel(). 1356 getLeadSelectionIndex() == 1357 column); 1358 return table.isFocusOwner() && (rowIsLead && colIsLead); 1359 1360 } 1361 1362 public String getColumnName(int columnIndex) { 1363 TableColumnModel columnModel = table.getColumnModel(); 1364 if (columnModel == null){ 1365 return "Column " + columnIndex; 1366 } 1367 TableColumn column = columnModel.getColumn(columnIndex); 1368 1369 return column == null ? "" : column.getHeaderValue().toString(); 1370 } 1371 1372 public int getColumnCount() { 1373 return table.getModel().getColumnCount(); 1374 } 1375 1376 public int getRowCount() { 1377 return table.getModel().getRowCount(); 1378 } 1379 1380 1383 public Object getValueAt(int row, int column) { 1384 return table.getModel().getValueAt(row, viewToModel(column)); 1385 } 1386 1387 public Object getFilteredValueAt(int row, int column) { 1388 return table.getValueAt(row, column); } 1390 1391 public void setValueAt(Object aValue, int row, int column) { 1392 table.getModel().setValueAt(aValue, row, viewToModel(column)); 1393 } 1394 1395 public boolean isCellEditable(int row, int column) { 1396 return table.getModel().isCellEditable(row, viewToModel(column)); 1397 } 1398 1399 1402 public boolean isSelected() { 1403 if (table instanceof JXTable && ( (JXTable) table).isPrinting()) { 1405 return false; 1406 } 1407 return table.isCellSelected(row, column); 1408 } 1409 1410 1413 public int modelToView(int columnIndex) { 1414 return table.convertColumnIndexToView(columnIndex); 1415 } 1416 1417 1420 public int viewToModel(int columnIndex) { 1421 return table.convertColumnIndexToModel(columnIndex); 1422 } 1423 1424 } 1425 1426 private static class Selection { 1427 protected final int[] selected; protected int lead = -1; 1429 protected Selection(JXTable table) { 1430 selected = table.getSelectedRows(); for (int i = 0; i < selected.length; i++) { 1432 selected[i] = table.convertRowIndexToModel(selected[i]); } 1434 1435 if (selected.length > 0) { 1436 lead = table.convertRowIndexToModel( 1438 table.getSelectionModel().getLeadSelectionIndex()); 1439 } 1440 } 1441 } 1442 1443 1452 public static class NumberRenderer extends DefaultTableCellRenderer { 1453 public NumberRenderer() { 1454 super(); 1455 setHorizontalAlignment(JLabel.RIGHT); 1456 } 1457 } 1458 1459 public static class DoubleRenderer extends NumberRenderer { 1460 NumberFormat formatter; 1461 public DoubleRenderer() { 1462 super(); 1463 } 1464 1465 public void setValue(Object value) { 1466 if (formatter == null) { 1467 formatter = NumberFormat.getInstance(); 1468 } 1469 setText( (value == null) ? "" : formatter.format(value)); 1470 } 1471 } 1472 1473 public static class DateRenderer extends DefaultTableCellRenderer { 1474 DateFormat formatter; 1475 public DateRenderer() { 1476 super(); 1477 } 1478 1479 public void setValue(Object value) { 1480 if (formatter == null) { 1481 formatter = DateFormat.getDateInstance(); 1482 } 1483 setText( (value == null) ? "" : formatter.format(value)); 1484 } 1485 } 1486 1487 public static class IconRenderer extends DefaultTableCellRenderer { 1488 public IconRenderer() { 1489 super(); 1490 setHorizontalAlignment(JLabel.CENTER); 1491 } 1492 1493 public void setValue(Object value) { 1494 setIcon( (value instanceof Icon ) ? (Icon ) value : null); 1495 } 1496 } 1497 1498 public static class BooleanRenderer extends JCheckBox 1499 implements TableCellRenderer { 1500 public BooleanRenderer() { 1501 super(); 1502 setHorizontalAlignment(JLabel.CENTER); 1503 } 1504 1505 public Component getTableCellRendererComponent(JTable table, 1506 Object value, 1507 boolean isSelected, boolean hasFocus, int row, int column) { 1508 if (isSelected) { 1509 setForeground(table.getSelectionForeground()); 1510 super.setBackground(table.getSelectionBackground()); 1511 } 1512 else { 1513 setForeground(table.getForeground()); 1514 setBackground(table.getBackground()); 1515 } 1516 setSelected( (value != null && ( (Boolean ) value).booleanValue())); 1517 return this; 1518 } 1519 } 1520 1521 1524 public static class LinkRenderer extends DefaultTableCellRenderer { 1525 1526 private static Color colorLive = new Color (0, 0, 238); 1528 private static Color colorVisited = new Color (82, 24, 139); 1529 1530 public void setValue(Object value) { 1531 if (value != null && value instanceof Link) { 1532 Link link = (Link) value; 1533 1534 setText(link.getText()); 1535 setToolTipText(link.getURL().toString()); 1536 1537 if (link.getVisited()) { 1538 setForeground(colorVisited); 1539 } 1540 else { 1541 setForeground(colorLive); 1542 } 1543 } 1544 else { 1545 super.setValue(value != null ? value.toString() : ""); 1546 } 1547 } 1548 1549 public void paintComponent(Graphics g) { 1550 super.paintComponent(g); 1551 if (!getText().equals("")) { 1552 Rectangle rect = PaintUtils.getTextBounds(g, this); 1556 1557 FontMetrics fm = g.getFontMetrics(); 1558 int descent = fm.getDescent(); 1559 1560 1563 g.drawLine(rect.x, (rect.y + rect.height) - descent + 1, 1564 rect.x + rect.width, 1565 (rect.y + rect.height) - descent + 1); 1566 } 1567 } 1568 } 1569} 1570 | Popular Tags |