1 7 8 package org.jdesktop.jdnc; 9 10 import java.awt.Color ; 11 import java.awt.Dimension ; 12 import java.awt.Font ; 13 import java.awt.Insets ; 14 import java.awt.event.ActionEvent ; 15 import java.awt.event.MouseAdapter ; 16 import java.awt.event.MouseEvent ; 17 import java.awt.print.PrinterException ; 18 import java.beans.PropertyChangeEvent ; 19 import java.beans.PropertyChangeListener ; 20 import java.io.IOException ; 21 import java.net.URL ; 22 23 import javax.swing.AbstractAction ; 24 import javax.swing.Action ; 25 import javax.swing.Icon ; 26 import javax.swing.JButton ; 27 import javax.swing.JCheckBoxMenuItem ; 28 import javax.swing.JPopupMenu ; 29 import javax.swing.JScrollPane ; 30 import javax.swing.JTable ; 31 import javax.swing.ScrollPaneConstants ; 32 import javax.swing.event.ChangeEvent ; 33 import javax.swing.event.ListSelectionEvent ; 34 import javax.swing.event.TableColumnModelEvent ; 35 import javax.swing.event.TableColumnModelListener ; 36 import javax.swing.event.TableModelEvent ; 37 import javax.swing.event.TableModelListener ; 38 import javax.swing.table.DefaultTableCellRenderer ; 39 import javax.swing.table.DefaultTableModel ; 40 import javax.swing.table.JTableHeader ; 41 import javax.swing.table.TableCellRenderer ; 42 import javax.swing.table.TableColumn ; 43 import javax.swing.table.TableColumnModel ; 44 import javax.swing.table.TableModel ; 45 46 import org.jdesktop.swing.JXTable; 47 import org.jdesktop.swing.JXTreeTable; 48 import org.jdesktop.swing.data.DefaultTableModelExt; 49 import org.jdesktop.swing.decorator.FilterPipeline; 50 import org.jdesktop.swing.decorator.Highlighter; 51 import org.jdesktop.swing.decorator.HighlighterPipeline; 52 import org.jdesktop.swing.icon.ColumnControlIcon; 53 import org.jdesktop.swing.table.ColumnHeaderRenderer; 54 import org.jdesktop.swing.table.DefaultTableColumnModelExt; 55 import org.jdesktop.swing.table.TableCellRenderers; 56 import org.jdesktop.swing.table.TableColumnExt; 57 import org.jdesktop.swing.table.TableColumnModelExt; 58 59 75 public class JNTable extends JNComponent { 76 81 public int DEFAULT_ROW_HEIGHT = 22; 82 87 public int DEFAULT_ROW_MARGIN = 1; 88 93 public int DEFAULT_VISIBLE_ROW_COUNT = 20; 94 99 public int DEFAULT_COLUMN_MARGIN = 0; 100 101 104 private boolean hasColumnControl = false; 105 109 private boolean rowHeaderLocked = false; 110 113 private JXTable rowHeaderTable = null; 114 private TableColumn firstColumn = null; 115 116 119 protected JScrollPane scrollPane; 120 124 protected JXTable jxtable; 125 126 130 private ColumnControlButton columnControlButton = null; 131 132 private ColumnPropertyHighlighter highlighter; 133 134 135 139 public JNTable() { 140 this(new DefaultTableModel ()); 141 } 142 143 150 public JNTable(TableModel model) { 151 this(new JXTable(model)); 152 } 153 154 159 public JNTable(URL url) { 160 setTable(new JXTable()); 161 DefaultTableModelExt model = new DefaultTableModelExt(url); 162 setModel(model); 163 try { 164 model.startLoading(); 165 } catch (IOException ioe) { 166 sendMessage(ioe.getMessage()); 167 } 168 initUI(); 169 } 170 171 protected JNTable(JTable jxtable) { 172 setTable((JXTable)jxtable); 173 setModel(jxtable.getModel()); 174 initUI(); 175 } 176 177 180 private void initUI() { 181 setRowHeight(DEFAULT_ROW_HEIGHT); 182 setRowMargin(DEFAULT_ROW_MARGIN); 183 scrollPane = new JScrollPane (jxtable); 184 add(scrollPane); } 186 187 195 protected void setTable(JXTable jxtable) { 196 this.jxtable = jxtable; 197 setComponent(jxtable); 198 } 199 200 204 public JXTable getTable() { 205 return jxtable; 206 } 207 208 214 public void setModel(TableModel model) { 215 TableModel oldModel = jxtable.getModel(); 216 if (!(jxtable instanceof JXTreeTable)) { 218 jxtable.setModel(model); 219 firePropertyChange("model", oldModel, model); 220 } 221 model.addTableModelListener(new TableModelAdapter()); 223 } 224 225 229 public TableModel getModel() { 230 return jxtable.getModel(); 231 } 232 233 237 public void addColumn(TableColumnExt column) { 238 jxtable.addColumn(column); 239 } 240 241 244 public void removeColumn(TableColumnExt column) { 245 jxtable.removeColumn(column); 246 } 247 248 253 public TableColumnExt getColumn(String name) { 254 return jxtable.getColumnExt(name); 255 } 256 257 268 public TableColumnExt getColumn(int currentViewIndex) { 269 return jxtable.getColumnExt(currentViewIndex); 270 } 271 272 276 public Color getOddRowBackground() { 277 return highlighter != null? highlighter.getOddRowBackground() : null; 278 } 279 280 287 public void setOddRowBackground(Color color) { 288 initHighlighter(); 289 Color old = highlighter.getOddRowBackground(); 290 highlighter.setOddRowBackground(color); 291 firePropertyChange("oddRowBackground", old, color); 292 } 293 294 298 public Color getEvenRowBackground() { 299 return highlighter != null? highlighter.getEvenRowBackground() : null; 300 } 301 302 307 public void setEvenRowBackground(Color color) { 308 initHighlighter(); 309 Color old = highlighter.getEvenRowBackground(); 310 highlighter.setEvenRowBackground(color); 311 firePropertyChange("evenRowBackground", old, color); 312 } 313 314 317 private void initHighlighter() { 318 if (highlighter == null) { 319 highlighter = new ColumnPropertyHighlighter(); 320 321 HighlighterPipeline pipeline = jxtable.getHighlighters(); 322 if (pipeline != null) { 323 pipeline.addHighlighter(highlighter, true); 325 } else { 326 pipeline = new HighlighterPipeline(new Highlighter[] { highlighter }); 327 jxtable.setHighlighters(pipeline); 328 } 329 } 330 } 331 332 337 public boolean getHasColumnControl() { 338 return hasColumnControl; 339 } 340 341 350 public void setHasColumnControl(boolean hasControl) { 351 boolean old = this.hasColumnControl; 352 if (hasControl) { 353 if (columnControlButton == null) { 354 columnControlButton = new ColumnControlButton(new ColumnControlIcon()); 356 } 357 scrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, columnControlButton); 359 360 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 361 } 362 else { 363 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 364 365 try { 366 scrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER, null); 367 } 368 catch (Exception ex) { 369 } 371 } 372 hasColumnControl = hasControl; 373 firePropertyChange("hasColumnControl", old, hasControl); 374 } 375 376 379 public boolean isRowHeaderLocked() { 380 return rowHeaderLocked; 381 } 382 383 388 public void setRowHeaderLocked(boolean lockState) { 389 if (rowHeaderLocked != lockState) { 390 if (firstColumn == null) { 391 firstColumn = initRowHeader(); 392 } 393 if (lockState) { 394 lockRowHeader(); 395 } 396 else { 397 unlockRowHeader(); 398 } 399 rowHeaderLocked = lockState; 400 } 401 } 402 403 protected TableColumn initRowHeader() { 404 rowHeaderTable = new JXTable(); 405 rowHeaderTable.setAutoCreateColumnsFromModel(false); 406 rowHeaderTable.setModel(jxtable.getModel()); 407 408 TableColumnModel tableColumnModel = jxtable.getColumnModel(); 409 TableColumn firstColumn = tableColumnModel.getColumn(0); 410 411 rowHeaderTable.addColumn(firstColumn); 412 rowHeaderTable.setSelectionModel(jxtable.getSelectionModel()); 413 rowHeaderTable.setRowHeight(jxtable.getRowHeight()); 414 415 rowHeaderTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 417 rowHeaderTable.getTableHeader().setReorderingAllowed(false); 418 rowHeaderTable.getTableHeader().setResizingAllowed(false); 419 rowHeaderTable.setPreferredScrollableViewportSize( 420 new Dimension (firstColumn.getPreferredWidth() + 421 rowHeaderTable.getColumnModel().getColumnMargin(), 0)); 422 423 428 return firstColumn; 429 } 430 431 protected void lockRowHeader() { 432 TableColumnModel tableColumnModel = jxtable.getColumnModel(); 433 tableColumnModel.removeColumn(firstColumn); 434 scrollPane.setRowHeaderView(rowHeaderTable); 435 scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, 436 rowHeaderTable.getTableHeader()); 437 jxtable.revalidate(); 438 } 439 440 protected void unlockRowHeader() { 441 TableColumnModel tableColumnModel = jxtable.getColumnModel(); 442 tableColumnModel.addColumn(firstColumn); 443 int numColumns = tableColumnModel.getColumnCount(); 444 tableColumnModel.moveColumn(numColumns - 1, 0); 445 scrollPane.setRowHeaderView(null); 446 jxtable.revalidate(); 447 } 448 449 453 public int getRowHeight() { 454 return jxtable.getRowHeight(); 455 } 456 457 462 public void setRowHeight(int value) { 463 int old = jxtable.getRowHeight(); 464 jxtable.setRowHeight(value); 465 firePropertyChange("rowHeight", old, value); 466 } 467 468 473 public int getPreferredVisibleRowCount() { 474 return jxtable.getVisibleRowCount(); 475 } 476 477 489 public void setPreferredVisibleRowCount(int value) { 490 int old = jxtable.getVisibleRowCount(); 491 jxtable.setVisibleRowCount(value); 492 firePropertyChange("preferredVisibleRowCount", old, value); 493 } 494 495 public int getColumnMargin() { 496 return jxtable.getColumnMargin(); 497 } 498 499 public void setColumnMargin(int value) { 500 jxtable.setColumnMargin(value); 501 } 502 503 public int getRowMargin() { 504 return jxtable.getRowMargin(); 505 } 506 507 public void setRowMargin(int value) { 508 jxtable.setRowMargin(value); 509 } 510 511 public int getSelectionMode() { 512 return jxtable.getSelectionMode(); 513 } 514 515 public void setSelectionMode(int mode) { 516 jxtable.setSelectionMode(mode); 517 } 518 519 public boolean getShowHorizontalLines() { 520 return jxtable.getShowHorizontalLines(); 521 } 522 523 public void setShowHorizontalLines(boolean value) { 524 jxtable.setShowHorizontalLines(value); 525 } 526 527 public boolean getShowVerticalLines() { 528 return jxtable.getShowVerticalLines(); 529 } 530 531 public void setShowVerticalLines(boolean value) { 532 jxtable.setShowVerticalLines(value); 533 } 534 535 public FilterPipeline getFilters() { 536 return jxtable.getFilters(); 537 } 538 539 public void setFilters(FilterPipeline pipeline) { 540 jxtable.setFilters(pipeline); 541 } 542 543 public HighlighterPipeline getHighlighters() { 544 return jxtable.getHighlighters(); 545 } 546 547 public void setHighlighters(HighlighterPipeline pipeline) { 548 552 jxtable.setHighlighters(pipeline); 553 } 554 555 public void setBackground(Color color) { 556 if (jxtable != null) { 558 jxtable.setBackground(color); 559 } 560 super.setBackground(color); 561 } 562 563 public void setForeground(Color color) { 564 if (jxtable != null) { 566 jxtable.setForeground(color); 567 } 568 super.setForeground(color); 569 } 570 571 public void setFont(Font font) { 572 if (jxtable != null) { 574 jxtable.setFont(font); 575 } 576 super.setFont(font); 577 } 578 579 public void setGridColor(Color color) { 580 jxtable.setGridColor(color); 581 } 582 583 586 587 592 public void setHeaderBackground(Color headerBackground) { 593 JTableHeader header = jxtable.getTableHeader(); 594 if (header != null) { 595 header.setBackground(headerBackground); 596 } 597 } 598 599 603 public Color getHeaderBackground() { 604 JTableHeader header = jxtable.getTableHeader(); 605 if (header != null) { 606 return header.getBackground(); 607 } 608 return null; 609 } 610 611 616 public void setHeaderForeground(Color headerForeground) { 617 JTableHeader header = getTable().getTableHeader(); 618 if (header != null) { 619 header.setForeground(headerForeground); 620 } 621 } 622 623 627 public Color getHeaderForeground() { 628 JTableHeader header = getTable().getTableHeader(); 629 if (header != null) { 630 return header.getForeground(); 631 } 632 return null; 633 } 634 635 640 public void setHeaderFont(Font headerFont) { 641 JTableHeader header = getTable().getTableHeader(); 642 if (header != null) { 643 header.setFont(headerFont); 644 } 645 } 646 647 651 public Font getHeaderFont() { 652 JTableHeader header = getTable().getTableHeader(); 653 if (header != null) { 654 return header.getFont(); 655 } 656 return null; 657 } 658 659 private ColumnHeaderRenderer getColumnHeaderRenderer() { 660 JTableHeader header = getTable().getTableHeader(); 661 if (header != null) { 662 TableCellRenderer hr = header.getDefaultRenderer(); 663 if (hr instanceof ColumnHeaderRenderer) { 664 return (ColumnHeaderRenderer) hr; 665 } 666 } 667 return null; 668 } 669 670 676 public void setHeaderSortUpIcon(Icon upIcon) { 677 ColumnHeaderRenderer headerRenderer = getColumnHeaderRenderer(); 678 if (headerRenderer != null) { 679 headerRenderer.setUpIcon(upIcon); 680 } 681 } 682 683 687 public Icon getHeaderSortUpIcon() { 688 ColumnHeaderRenderer headerRenderer = getColumnHeaderRenderer(); 689 if (headerRenderer != null) { 690 return headerRenderer.getUpIcon(); 691 } 692 return null; 693 } 694 695 701 public void setHeaderSortDownIcon(Icon downIcon) { 702 ColumnHeaderRenderer headerRenderer = getColumnHeaderRenderer(); 703 if (headerRenderer != null) { 704 headerRenderer.setDownIcon(downIcon); 705 } 706 } 707 708 712 public Icon getHeaderSortDownIcon() { 713 ColumnHeaderRenderer headerRenderer = getColumnHeaderRenderer(); 714 if (headerRenderer != null) { 715 return headerRenderer.getDownIcon(); 716 } 717 return null; 718 } 719 720 723 724 730 public Class getColumnClass(String columnName) { 731 return jxtable.getColumnClass(jxtable.getColumnModel(). 732 getColumnIndex(columnName)); 733 } 734 735 744 public void setColumnBackground(String columnName, Color background) { 745 initHighlighter(); 746 highlighter.setColumnBackground(columnName, background); 747 } 748 749 754 public Color getColumnBackground(String columnName) { 755 return highlighter != null? highlighter.getColumnBackground(columnName) : null; 756 } 757 758 767 public void setColumnForeground(String columnName, Color foreground) { 768 initHighlighter(); 769 highlighter.setColumnForeground(columnName, foreground); 770 } 771 772 777 public Color getColumnForeground(String columnName) { 778 return highlighter != null? highlighter.getColumnForeground(columnName) : null; 779 } 780 781 789 public void setColumnFont(String columnName, Font font) { 790 initHighlighter(); 791 highlighter.setColumnFont(columnName, font); 792 } 793 794 799 public Font getColumnFont(String columnName) { 800 return highlighter != null? highlighter.getColumnFont(columnName) : null; 801 } 802 803 816 public void setColumnHorizontalAlignment(String columnName, int alignment) { 817 825 TableColumnExt column = getColumn(columnName); 826 TableCellRenderer renderer = column.getCellRenderer(); 827 if (renderer == null) { 828 renderer = TableCellRenderers.getNewDefaultRenderer(getColumnClass( 829 columnName)); 830 column.setCellRenderer(renderer); 831 if (renderer instanceof DefaultTableCellRenderer ) { 832 column.putClientProperty("saveAlignment", 833 new Integer (((DefaultTableCellRenderer )renderer).getHorizontalAlignment())); 834 } 835 } 836 column.putClientProperty("alignment", new Integer (alignment)); 837 if (renderer != null && renderer instanceof DefaultTableCellRenderer ) { 838 if (alignment != -1) { 839 ((DefaultTableCellRenderer )renderer).setHorizontalAlignment(alignment); 840 } else { 841 Integer restoreAlignment = (Integer )column.getClientProperty("saveAlignment"); 843 if (restoreAlignment != null) { 844 ((DefaultTableCellRenderer )renderer).setHorizontalAlignment( 845 restoreAlignment.intValue()); 846 } 847 } 848 } 849 } 850 851 856 public int getColumnHorizontalAlignment(String columnName) { 857 TableColumnExt column = getColumn(columnName); 858 Integer alignment = (Integer )column.getClientProperty("alignment"); 859 return alignment != null? alignment.intValue() : -1; 860 } 861 862 874 public void setColumnPrototypeValue(String columnName, Object prototype) { 875 TableColumnExt column = getColumn(columnName); 876 column.setPrototypeValue(prototype); 877 } 878 879 884 public Object getColumnPrototypeValue(String columnName) { 885 TableColumnExt column = getColumn(columnName); 886 return column.getPrototypeValue(); 887 } 888 889 public boolean print() throws PrinterException { 890 boolean printed = getTable().print(); 891 sendMessage("Print " + (printed? "complete." : "cancelled.")); 892 return printed; 893 } 894 895 917 918 private class TableModelAdapter implements TableModelListener { 919 920 public void tableChanged(TableModelEvent e) { 921 if (e.getFirstRow() == TableModelEvent.HEADER_ROW) { 922 if (columnControlButton != null) { 923 } 926 } 927 setRowColumnStatus(); 929 } 930 } 931 932 private void setRowColumnStatus() { 933 TableColumnModel columnModel = jxtable.getColumnModel(); 934 TableModel model = jxtable.getModel(); 935 936 if (support != null) { 937 support.fireMessage(model.getRowCount() + " rows, " + 938 columnModel.getColumnCount() + " columns"); 939 } 940 } 941 942 public String toString() { 943 return super.toString() + "; " + getTable().toString(); 944 } 945 946 947 954 private final class ColumnControlButton extends JButton { 955 958 public final static String TITLE = "x"; 959 960 private JPopupMenu popupMenu = null; 961 962 private MouseAdapter mouseListener = new MouseAdapter () { 963 public void mousePressed(MouseEvent ev) { 964 if (popupMenu.getComponentCount() > 0) { 965 JButton button = ColumnControlButton.this; 966 Dimension buttonSize = button.getSize(); 967 popupMenu.show(button, 968 buttonSize.width - 969 popupMenu.getPreferredSize().width, 970 buttonSize.height); 971 } 972 } 973 }; 974 975 private PropertyChangeListener columnModelChangeListener = new PropertyChangeListener () { 976 public void propertyChange(PropertyChangeEvent evt) { 977 ((TableColumnModel )evt.getOldValue()).removeColumnModelListener(columnModelListener); 978 if (((TableColumnModel )evt.getNewValue()) instanceof TableColumnModelExt) { 979 setEnabled(true); 980 ((TableColumnModel )evt.getNewValue()).addColumnModelListener(columnModelListener); 981 populatePopupMenu(); 982 } else { 983 setEnabled(false); 984 } 985 } 986 }; 987 988 private TableColumnModelListener columnModelListener = new TableColumnModelListener () { 989 990 public void columnAdded(TableColumnModelEvent e) { 991 if (isVisibilityChange(e, true)) return; 992 populatePopupMenu(); 993 } 994 995 996 public void columnRemoved(TableColumnModelEvent e) { 997 if (isVisibilityChange(e, false)) return; 998 populatePopupMenu(); 999 } 1000 1001 1012 private boolean isVisibilityChange(TableColumnModelEvent e, boolean added) { 1013 if (!(e.getSource() instanceof DefaultTableColumnModelExt)) return false; 1015 DefaultTableColumnModelExt model = (DefaultTableColumnModelExt) e.getSource(); 1016 if (added) { 1017 return model.isAddedFromInvisibleEvent(e.getToIndex()); 1018 } else { 1019 return model.isRemovedToInvisibleEvent(e.getFromIndex()); 1020 } 1021 } 1022 1023 public void columnMoved(TableColumnModelEvent e){} 1024 1025 1026 public void columnMarginChanged(ChangeEvent e){} 1027 1028 1032 public void columnSelectionChanged(ListSelectionEvent e){} 1033 }; 1034 1035 public ColumnControlButton() { 1036 super(TITLE); 1037 init(); 1038 } 1039 public ColumnControlButton(Action action) { 1040 super(action); 1041 init(); 1042 } 1043 public ColumnControlButton(Icon icon) { 1044 super(icon); 1045 init(); 1046 } 1047 public ColumnControlButton(String title) { 1048 super(title); 1049 init(); 1050 } 1051 public ColumnControlButton(String title, Icon icon) { 1052 super(title, icon); 1053 init(); 1054 } 1055 1056 1059 private void init() { 1060 setFocusPainted(false); 1061 setMargin(new Insets (1,2,2,1)); 1063 setEnabled(jxtable.getColumnModel() instanceof TableColumnModelExt); 1064 1065 popupMenu = new JPopupMenu (); 1067 populatePopupMenu(); 1069 jxtable.addPropertyChangeListener("columnModel", columnModelChangeListener); 1072 jxtable.getColumnModel().addColumnModelListener(columnModelListener); 1073 1074 } 1075 1076 1080 protected void populatePopupMenu() { 1081 popupMenu.removeAll(); 1082 TableColumnModel columnModel = jxtable.getColumnModel(); 1084 for (int i=0; i<columnModel.getColumnCount(); i++) { 1085 TableColumn column = columnModel.getColumn(i); 1086 JCheckBoxMenuItem item = new JCheckBoxMenuItem ( 1088 column.getHeaderValue().toString(), true); 1089 item.putClientProperty("column", column); 1090 item.addActionListener(columnVisibilityAction); 1092 popupMenu.add(item); } 1094 } 1095 1096 private AbstractAction columnVisibilityAction = new AbstractAction () { 1097 public void actionPerformed(ActionEvent ev) { 1098 JCheckBoxMenuItem item = (JCheckBoxMenuItem ) ev.getSource(); 1099 TableColumnExt column = (TableColumnExt) item.getClientProperty("column"); 1100 if (item.isSelected()) { column.setVisible(true); 1102 1103 } 1104 else { 1105 TableColumnModelExt model = (TableColumnModelExt)jxtable.getColumnModel(); 1107 if (model.getColumnCount() - 1 == 0) { 1108 item.setSelected(true); 1110 } else { 1111 column.setVisible(false); 1112 } 1113 } 1114 } 1115 }; 1116 1117 public void setEnabled(boolean b) { 1118 if (b && jxtable.getColumnModel() instanceof TableColumnModelExt) { 1119 removeMouseListener(mouseListener); 1121 addMouseListener(mouseListener); 1122 } else { 1123 removeMouseListener(mouseListener); 1124 } 1125 super.setEnabled(b); 1126 } 1127 } } | Popular Tags |