001: /*
002: * @(#)TreeTableModelAdapter.java 1.2 98/10/27
003: *
004: * Copyright 1997, 1998 by Sun Microsystems, Inc.,
005: * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
006: * All rights reserved.
007: *
008: * This software is the confidential and proprietary information
009: * of Sun Microsystems, Inc. ("Confidential Information"). You
010: * shall not disclose such Confidential Information and shall use
011: * it only in accordance with the terms of the license agreement
012: * you entered into with Sun.
013: */
014: package gruntspud.ui.treetable;
015:
016: import javax.swing.JTree;
017: import javax.swing.SwingUtilities;
018: import javax.swing.table.AbstractTableModel;
019: import javax.swing.tree.TreePath;
020: import javax.swing.event.TreeExpansionEvent;
021: import javax.swing.event.TreeExpansionListener;
022: import javax.swing.event.TreeModelEvent;
023: import javax.swing.event.TreeModelListener;
024:
025: /**
026: * This is a wrapper class takes a TreeTableModel and implements
027: * the table model interface. The implementation is trivial, with
028: * all of the event dispatching support provided by the superclass:
029: * the AbstractTableModel.
030: *
031: * @version 1.2 10/27/98
032: *
033: * @author Philip Milne
034: * @author Scott Violet
035: */
036: public class TreeTableModelAdapter extends AbstractTableModel {
037: JTree tree;
038: TreeTableModel treeTableModel;
039:
040: public TreeTableModelAdapter(TreeTableModel treeTableModel,
041: JTree tree) {
042: this .tree = tree;
043: this .treeTableModel = treeTableModel;
044:
045: tree.addTreeExpansionListener(new TreeExpansionListener() {
046: // Don't use fireTableRowsInserted() here; the selection model
047: // would get updated twice.
048: public void treeExpanded(TreeExpansionEvent event) {
049: fireTableDataChanged();
050: }
051:
052: public void treeCollapsed(TreeExpansionEvent event) {
053: fireTableDataChanged();
054: }
055: });
056:
057: // Install a TreeModelListener that can update the table when
058: // tree changes. We use delayedFireTableDataChanged as we can
059: // not be guaranteed the tree will have finished processing
060: // the event before us.
061: treeTableModel.addTreeModelListener(new TreeModelListener() {
062: public void treeNodesChanged(TreeModelEvent e) {
063: delayedFireTableDataChanged();
064: }
065:
066: public void treeNodesInserted(TreeModelEvent e) {
067: delayedFireTableDataChanged();
068: }
069:
070: public void treeNodesRemoved(TreeModelEvent e) {
071: delayedFireTableDataChanged();
072: }
073:
074: public void treeStructureChanged(TreeModelEvent e) {
075: delayedFireTableDataChanged();
076: }
077: });
078: }
079:
080: // Wrappers, implementing TableModel interface.
081:
082: public int getColumnCount() {
083: return treeTableModel.getColumnCount();
084: }
085:
086: public String getColumnName(int column) {
087: return treeTableModel.getColumnName(column);
088: }
089:
090: public Class getColumnClass(int column) {
091: return treeTableModel.getColumnClass(column);
092: }
093:
094: public int getRowCount() {
095: return tree.getRowCount();
096: }
097:
098: protected Object nodeForRow(int row) {
099: TreePath treePath = tree.getPathForRow(row);
100: return treePath.getLastPathComponent();
101: }
102:
103: public Object getValueAt(int row, int column) {
104: return treeTableModel.getValueAt(nodeForRow(row), column);
105: }
106:
107: public boolean isCellEditable(int row, int column) {
108: return treeTableModel.isCellEditable(nodeForRow(row), column);
109: }
110:
111: public void setValueAt(Object value, int row, int column) {
112: treeTableModel.setValueAt(value, nodeForRow(row), column);
113: }
114:
115: /**
116: * Invokes fireTableDataChanged after all the pending events have been
117: * processed. SwingUtilities.invokeLater is used to handle this.
118: */
119: protected void delayedFireTableDataChanged() {
120: SwingUtilities.invokeLater(new Runnable() {
121: public void run() {
122: fireTableDataChanged();
123: }
124: });
125: }
126: }
|