1 29 30 package nextapp.echo2.app; 31 32 import java.util.EventListener ; 33 import java.util.HashMap ; 34 import java.util.Map ; 35 36 import nextapp.echo2.app.event.ActionEvent; 37 import nextapp.echo2.app.event.ActionListener; 38 import nextapp.echo2.app.event.ChangeEvent; 39 import nextapp.echo2.app.event.ChangeListener; 40 import nextapp.echo2.app.event.TableColumnModelEvent; 41 import nextapp.echo2.app.event.TableColumnModelListener; 42 import nextapp.echo2.app.event.TableModelEvent; 43 import nextapp.echo2.app.event.TableModelListener; 44 import nextapp.echo2.app.list.DefaultListSelectionModel; 45 import nextapp.echo2.app.list.ListSelectionModel; 46 import nextapp.echo2.app.table.DefaultTableCellRenderer; 47 import nextapp.echo2.app.table.DefaultTableColumnModel; 48 import nextapp.echo2.app.table.DefaultTableModel; 49 import nextapp.echo2.app.table.TableCellRenderer; 50 import nextapp.echo2.app.table.TableColumn; 51 import nextapp.echo2.app.table.TableColumnModel; 52 import nextapp.echo2.app.table.TableModel; 53 54 59 public class Table extends Component { 60 61 64 public static final TableCellRenderer DEFAULT_TABLE_CELL_RENDERER = new DefaultTableCellRenderer(); 65 66 public static final String PROPERTY_ACTION_COMMAND = "actionCommand"; 67 public static final String PROPERTY_BORDER = "border"; 68 public static final String PROPERTY_INSETS = "insets"; 69 public static final String PROPERTY_ROLLOVER_BACKGROUND = "rolloverBackground"; 70 public static final String PROPERTY_ROLLOVER_BACKGROUND_IMAGE = "rolloverBackgroundImage"; 71 public static final String PROPERTY_ROLLOVER_ENABLED = "rolloverEnabled"; 72 public static final String PROPERTY_ROLLOVER_FONT = "rolloverFont"; 73 public static final String PROPERTY_ROLLOVER_FOREGROUND = "rolloverForeground"; 74 public static final String PROPERTY_SELECTION_BACKGROUND = "selectionBackground"; 75 public static final String PROPERTY_SELECTION_BACKGROUND_IMAGE = "selectionBackgroundImage"; 76 public static final String PROPERTY_SELECTION_ENABLED = "selectionEnabled"; 77 public static final String PROPERTY_SELECTION_FONT = "selectionFont"; 78 public static final String PROPERTY_SELECTION_FOREGROUND= "selectionForeground"; 79 public static final String PROPERTY_WIDTH = "width"; 80 81 public static final String INPUT_ACTION = "action"; 82 83 public static final String ACTION_LISTENERS_CHANGED_PROPERTY = "actionListeners"; 84 public static final String AUTO_CREATE_COLUMNS_FROM_MODEL_CHANGED_PROPERTY = "autoCreateColumnsFromModel"; 85 public static final String COLUMN_MODEL_CHANGED_PROPERTY = "columnModel"; 86 public static final String DEFAULT_HEADER_RENDERER_CHANGED_PROPERTY = "defaultHeaderRenderer"; 87 public static final String DEFAULT_RENDERER_CHANGED_PROPERTY = "defaultRenderer"; 88 public static final String HEADER_VISIBLE_CHANGED_PROPERTY = "headerVisible"; 89 public static final String MODEL_CHANGED_PROPERTY = "model"; 90 public static final String SELECTION_CHANGED_PROPERTY = "selection"; 91 public static final String SELECTION_MODEL_CHANGED_PROPERTY = "selectionModel"; 92 93 public static final int HEADER_ROW = -1; 94 95 private boolean autoCreateColumnsFromModel; 96 private boolean headerVisible = true; 97 private TableModel model; 98 private TableColumnModel columnModel; 99 private boolean valid; 100 private Map defaultRendererMap = new HashMap (); 101 private TableCellRenderer defaultHeaderRenderer; 102 private ListSelectionModel selectionModel; 103 private boolean suppressChangeNotifications; 104 105 108 private TableModelListener modelListener = new TableModelListener() { 109 110 113 public void tableChanged(TableModelEvent e) { 114 invalidate(); 115 if ((e == null || e.getType() == TableModelEvent.STRUCTURE_CHANGED) && isAutoCreateColumnsFromModel()) { 116 createDefaultColumnsFromModel(); 117 } 118 } 119 }; 120 121 124 private TableColumnModelListener columnModelListener = new TableColumnModelListener() { 125 126 129 public void columnAdded(TableColumnModelEvent e) { 130 invalidate(); 131 } 132 133 136 public void columnMoved(TableColumnModelEvent e) { 137 invalidate(); 138 } 139 140 143 public void columnRemoved(TableColumnModelEvent e) { 144 invalidate(); 145 } 146 }; 147 148 151 private ChangeListener changeHandler = new ChangeListener() { 152 153 156 public void stateChanged(ChangeEvent e) { 157 if (!suppressChangeNotifications) { 158 firePropertyChange(SELECTION_CHANGED_PROPERTY, null, null); 159 } 160 } 161 }; 162 163 167 public Table() { 168 this(new DefaultTableModel()); 169 } 170 171 178 public Table(int columns, int rows) { 179 this(new DefaultTableModel(columns, rows)); 180 } 181 182 188 public Table(TableModel model) { 189 this(model, null); 190 } 191 192 199 public Table(TableModel model, TableColumnModel columnModel) { 200 super(); 201 202 if (columnModel == null) { 203 setColumnModel(new DefaultTableColumnModel()); 204 setAutoCreateColumnsFromModel(true); 205 } else { 206 setColumnModel(columnModel); 207 } 208 setSelectionModel(new DefaultListSelectionModel()); 209 setModel(model); 210 } 211 212 219 public String getActionCommand() { 220 return (String ) getProperty(PROPERTY_ACTION_COMMAND); 221 } 222 223 230 public void addActionListener(ActionListener l) { 231 getEventListenerList().addListener(ActionListener.class, l); 232 firePropertyChange(ACTION_LISTENERS_CHANGED_PROPERTY, null, l); 235 } 236 237 243 public void createDefaultColumnsFromModel() { 244 if (model != null) { 245 while (columnModel.getColumnCount() > 0) { 246 columnModel.removeColumn(columnModel.getColumn(0)); 247 } 248 249 int columnCount = model.getColumnCount(); 250 for (int index = 0; index < columnCount; ++index) { 251 columnModel.addColumn(new TableColumn(index)); 252 } 253 } 254 } 255 256 259 protected void doRender() { 260 removeAll(); 261 int rowCount = model.getRowCount(); 262 int columnCount = columnModel.getColumnCount(); 263 264 TableColumn[] tableColumns = new TableColumn[columnCount]; 265 TableCellRenderer[] columnRenderers = new TableCellRenderer[columnCount]; 266 267 for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { 268 tableColumns[columnIndex] = columnModel.getColumn(columnIndex); 269 270 TableCellRenderer renderer = tableColumns[columnIndex].getCellRenderer(); 271 if (renderer == null) { 272 Class columnClass = model.getColumnClass(tableColumns[columnIndex].getModelIndex()); 273 renderer = getDefaultRenderer(columnClass); 274 if (renderer == null) { 275 renderer = DEFAULT_TABLE_CELL_RENDERER; 276 } 277 } 278 columnRenderers[columnIndex] = renderer; 279 280 } 281 282 if (isHeaderVisible()) { 283 for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { 284 int modelColumnIndex = tableColumns[columnIndex].getModelIndex(); 285 Object headerValue = tableColumns[columnIndex].getHeaderValue(); 286 if (headerValue == null) { 287 headerValue = model.getColumnName(modelColumnIndex); 288 } 289 TableCellRenderer headerRenderer = tableColumns[columnIndex].getHeaderRenderer(); 290 if (headerRenderer == null) { 291 headerRenderer = defaultHeaderRenderer; 292 if (headerRenderer == null) { 293 headerRenderer = DEFAULT_TABLE_CELL_RENDERER; 294 } 295 } 296 Component renderedComponent 297 = headerRenderer.getTableCellRendererComponent(this, headerValue, modelColumnIndex, HEADER_ROW); 298 if (renderedComponent == null) { 299 renderedComponent = new Label(); 300 } 301 add(renderedComponent); 302 } 303 } 304 305 for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { 306 for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex) { 307 int modelColumnIndex = tableColumns[columnIndex].getModelIndex(); 308 Object modelValue = model.getValueAt(modelColumnIndex, rowIndex); 309 Component renderedComponent 310 = columnRenderers[columnIndex].getTableCellRendererComponent(this, modelValue, modelColumnIndex, rowIndex); 311 if (renderedComponent == null) { 312 renderedComponent = new Label(); 313 } 314 add(renderedComponent); 315 } 316 } 317 } 318 319 322 private void fireActionEvent() { 323 if (!hasEventListenerList()) { 324 return; 325 } 326 EventListener [] listeners = getEventListenerList().getListeners(ActionListener.class); 327 ActionEvent e = null; 328 for (int i = 0; i < listeners.length; ++i) { 329 if (e == null) { 330 e = new ActionEvent(this, (String ) getRenderProperty(PROPERTY_ACTION_COMMAND)); 331 } 332 ((ActionListener) listeners[i]).actionPerformed(e); 333 } 334 } 335 336 341 public Border getBorder() { 342 return (Border) getProperty(PROPERTY_BORDER); 343 } 344 345 353 public Component getCellComponent(int column, int row) { 354 if (!valid) { 355 validate(); 356 } 357 if (isHeaderVisible()) { 358 return getComponent((row + 1) * columnModel.getColumnCount() + column); 359 } else { 360 if (row == HEADER_ROW) { 361 return null; 362 } else { 363 return getComponent(row * columnModel.getColumnCount() + column); 364 } 365 } 366 } 367 368 374 public TableColumnModel getColumnModel() { 375 return columnModel; 376 } 377 378 386 public TableCellRenderer getDefaultHeaderRenderer() { 387 return defaultHeaderRenderer; 388 } 389 390 398 public TableCellRenderer getDefaultRenderer(Class columnClass) { 399 return (TableCellRenderer) defaultRendererMap.get(columnClass); 400 } 401 402 407 public Insets getInsets() { 408 return (Insets) getProperty(PROPERTY_INSETS); 409 } 410 411 417 public TableModel getModel() { 418 return model; 419 } 420 421 427 public Color getRolloverBackground() { 428 return (Color) getProperty(PROPERTY_ROLLOVER_BACKGROUND); 429 } 430 431 437 public FillImage getRolloverBackgroundImage() { 438 return (FillImage) getProperty(PROPERTY_ROLLOVER_BACKGROUND_IMAGE); 439 } 440 441 447 public Font getRolloverFont() { 448 return (Font) getProperty(PROPERTY_ROLLOVER_FONT); 449 } 450 451 457 public Color getRolloverForeground() { 458 return (Color) getProperty(PROPERTY_ROLLOVER_FOREGROUND); 459 } 460 461 466 public Color getSelectionBackground() { 467 return (Color) getProperty(PROPERTY_SELECTION_BACKGROUND); 468 } 469 470 475 public FillImage getSelectionBackgroundImage() { 476 return (FillImage) getProperty(PROPERTY_SELECTION_BACKGROUND_IMAGE); 477 } 478 479 484 public Font getSelectionFont() { 485 return (Font) getProperty(PROPERTY_SELECTION_FONT); 486 } 487 488 493 public Color getSelectionForeground() { 494 return (Color) getProperty(PROPERTY_SELECTION_FOREGROUND); 495 } 496 497 502 public ListSelectionModel getSelectionModel() { 503 return selectionModel; 504 } 505 506 513 public Extent getWidth() { 514 return (Extent) getProperty(PROPERTY_WIDTH); 515 } 516 517 522 public boolean hasActionListeners() { 523 return getEventListenerList().getListenerCount(ActionListener.class) != 0; 524 } 525 526 529 protected void invalidate() { 530 valid = false; 531 } 532 533 544 public boolean isAutoCreateColumnsFromModel() { 545 return autoCreateColumnsFromModel; 546 } 547 548 553 public boolean isHeaderVisible() { 554 return headerVisible; 555 } 556 557 563 public boolean isRolloverEnabled() { 564 Boolean value = (Boolean ) getProperty(PROPERTY_ROLLOVER_ENABLED); 565 return value == null ? false : value.booleanValue(); 566 } 567 568 573 public boolean isSelectionEnabled() { 574 Boolean value = (Boolean ) getProperty(PROPERTY_SELECTION_ENABLED); 575 return value == null ? false : value.booleanValue(); 576 } 577 578 581 public void processInput(String inputName, Object inputValue) { 582 super.processInput(inputName, inputValue); 583 if (inputName.equals(SELECTION_CHANGED_PROPERTY)) { 584 setSelectedIndices((int[]) inputValue); 585 } else if (INPUT_ACTION.equals(inputName)) { 586 fireActionEvent(); 587 } 588 } 589 590 597 public void removeActionListener(ActionListener l) { 598 if (!hasEventListenerList()) { 599 return; 600 } 601 getEventListenerList().removeListener(ActionListener.class, l); 602 firePropertyChange(ACTION_LISTENERS_CHANGED_PROPERTY, l, null); 605 } 606 607 614 public void setActionCommand(String newValue) { 615 setProperty(PROPERTY_ACTION_COMMAND, newValue); 616 } 617 618 626 public void setAutoCreateColumnsFromModel(boolean newValue) { 627 boolean oldValue = autoCreateColumnsFromModel; 628 autoCreateColumnsFromModel = newValue; 629 630 if (!oldValue && newValue) { 631 createDefaultColumnsFromModel(); 632 } 633 634 firePropertyChange(AUTO_CREATE_COLUMNS_FROM_MODEL_CHANGED_PROPERTY, 635 Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); 636 } 637 638 643 public void setBorder(Border newValue) { 644 setProperty(PROPERTY_BORDER, newValue); 645 } 646 647 653 public void setColumnModel(TableColumnModel newValue) { 654 invalidate(); 655 656 if (newValue == null) { 657 throw new IllegalArgumentException ("The model may not be null."); 658 } 659 660 TableColumnModel oldValue = columnModel; 661 if (oldValue != null) { 662 oldValue.removeColumnModelListener(columnModelListener); 663 } 664 columnModel = newValue; 665 newValue.addColumnModelListener(columnModelListener); 666 firePropertyChange(COLUMN_MODEL_CHANGED_PROPERTY, oldValue, newValue); 667 } 668 669 677 public void setDefaultHeaderRenderer(TableCellRenderer newValue) { 678 invalidate(); 679 TableCellRenderer oldValue = defaultHeaderRenderer; 680 defaultHeaderRenderer = newValue; 681 firePropertyChange(DEFAULT_HEADER_RENDERER_CHANGED_PROPERTY, oldValue, newValue); 682 } 683 684 692 public void setDefaultRenderer(Class columnClass, TableCellRenderer newValue) { 693 invalidate(); 694 if (newValue == null) { 695 defaultRendererMap.remove(columnClass); 696 } else { 697 defaultRendererMap.put(columnClass, newValue); 698 } 699 firePropertyChange(DEFAULT_RENDERER_CHANGED_PROPERTY, null, null); 700 } 701 702 707 public void setHeaderVisible(boolean newValue) { 708 invalidate(); 709 boolean oldValue = headerVisible; 710 headerVisible = newValue; 711 firePropertyChange(HEADER_VISIBLE_CHANGED_PROPERTY, Boolean.valueOf(oldValue), Boolean.valueOf(newValue)); 712 } 713 714 719 public void setInsets(Insets newValue) { 720 setProperty(PROPERTY_INSETS, newValue); 721 } 722 723 728 public void setModel(TableModel newValue) { 729 invalidate(); 730 731 if (newValue == null) { 732 throw new IllegalArgumentException ("The model may not be null."); 733 } 734 735 TableModel oldValue = model; 736 if (oldValue != null) { 737 oldValue.removeTableModelListener(modelListener); 738 } 739 model = newValue; 740 newValue.addTableModelListener(modelListener); 741 742 if (isAutoCreateColumnsFromModel()) { 743 createDefaultColumnsFromModel(); 744 } 745 746 firePropertyChange(MODEL_CHANGED_PROPERTY, oldValue, newValue); 747 } 748 749 755 public void setRolloverBackground(Color newValue) { 756 setProperty(PROPERTY_ROLLOVER_BACKGROUND, newValue); 757 } 758 759 765 public void setRolloverBackgroundImage(FillImage newValue) { 766 setProperty(PROPERTY_ROLLOVER_BACKGROUND_IMAGE, newValue); 767 } 768 769 776 public void setRolloverEnabled(boolean newValue) { 777 setProperty(PROPERTY_ROLLOVER_ENABLED, new Boolean (newValue)); 778 } 779 780 786 public void setRolloverFont(Font newValue) { 787 setProperty(PROPERTY_ROLLOVER_FONT, newValue); 788 } 789 790 796 public void setRolloverForeground(Color newValue) { 797 setProperty(PROPERTY_ROLLOVER_FOREGROUND, newValue); 798 } 799 800 805 private void setSelectedIndices(int[] selectedIndices) { 806 suppressChangeNotifications = true; 808 ListSelectionModel selectionModel = getSelectionModel(); 809 selectionModel.clearSelection(); 810 for (int i = 0; i < selectedIndices.length; ++i) { 811 selectionModel.setSelectedIndex(selectedIndices[i], true); 812 } 813 suppressChangeNotifications = false; 815 firePropertyChange(SELECTION_CHANGED_PROPERTY, null, selectedIndices); 816 } 817 818 823 public void setSelectionBackground(Color newValue) { 824 setProperty(PROPERTY_SELECTION_BACKGROUND, newValue); 825 } 826 827 832 public void setSelectionBackgroundImage(FillImage newValue) { 833 setProperty(PROPERTY_SELECTION_BACKGROUND_IMAGE, newValue); 834 } 835 836 841 public void setSelectionEnabled(boolean newValue) { 842 setProperty(PROPERTY_SELECTION_ENABLED, Boolean.valueOf(newValue)); 843 } 844 845 850 public void setSelectionForeground(Color newValue) { 851 setProperty(PROPERTY_SELECTION_FOREGROUND, newValue); 852 } 853 854 859 public void setSelectionFont(Font newValue) { 860 setProperty(PROPERTY_SELECTION_FONT, newValue); 861 } 862 863 869 public void setSelectionModel(ListSelectionModel newValue) { 870 if (newValue == null) { 871 throw new IllegalArgumentException ("Selection model may not be null."); 872 } 873 ListSelectionModel oldValue = selectionModel; 874 if (oldValue != null) { 875 oldValue.removeChangeListener(changeHandler); 876 } 877 newValue.addChangeListener(changeHandler); 878 selectionModel = newValue; 879 firePropertyChange(SELECTION_MODEL_CHANGED_PROPERTY, oldValue, newValue); 880 } 881 882 889 public void setWidth(Extent newValue) { 890 setProperty(PROPERTY_WIDTH, newValue); 891 } 892 893 896 public void validate() { 897 super.validate(); 898 while (!valid) { 899 valid = true; 900 doRender(); 901 } 902 } 903 } 904 | Popular Tags |