001: package org.swingml.treetablebrowser.ext;
002:
003: import javax.swing.*;
004: import javax.swing.event.*;
005: import javax.swing.table.*;
006: import javax.swing.tree.*;
007:
008: import org.swingml.*;
009:
010: public class TreeTableBrowserModelAdapter extends AbstractTableModel {
011:
012: private final class TEL implements TreeExpansionListener {
013:
014: private String getName(final TreeExpansionEvent tee) {
015: SwingMLModel smlm = (SwingMLModel) tee.getPath()
016: .getLastPathComponent();
017: return smlm.getName();
018: }
019:
020: public void treeCollapsed(final TreeExpansionEvent tee) {
021: treeTableModel.collapse(getName(tee));
022: fireTableDataChanged();
023: }
024:
025: // Don't use fireTableRowsInserted() here; the selection model
026: // would get updated twice.
027: public void treeExpanded(final TreeExpansionEvent tee) {
028: treeTableModel.expand(getName(tee));
029: fireTableDataChanged();
030: }
031: }
032:
033: JTree tree;
034: TreeTableBrowserModelInterface treeTableModel;
035:
036: public TreeTableBrowserModelAdapter(
037: TreeTableBrowserModelInterface treeTableModel, JTree tree) {
038: this .tree = tree;
039: this .treeTableModel = treeTableModel;
040: tree.addTreeExpansionListener(new TEL());
041: // Install a TreeModelListener that can update the table when
042: // tree changes. We use delayedFireTableDataChanged as we can
043: // not be guaranteed the tree will have finished processing
044: // the event before us.
045: treeTableModel.addTreeModelListener(new TreeModelListener() {
046:
047: public void treeNodesChanged(TreeModelEvent e) {
048: delayedFireTableDataChanged();
049: }
050:
051: public void treeNodesInserted(TreeModelEvent e) {
052: delayedFireTableDataChanged();
053: }
054:
055: public void treeNodesRemoved(TreeModelEvent e) {
056: delayedFireTableDataChanged();
057: }
058:
059: public void treeStructureChanged(TreeModelEvent e) {
060: delayedFireTableDataChanged();
061: }
062: });
063: }
064:
065: public void applyFilters() {
066: treeTableModel.applyFilters();
067: }
068:
069: /**
070: * Invokes fireTableDataChanged after all the pending events have been
071: * processed. SwingUtilities.invokeLater is used to handle this.
072: */
073: protected void delayedFireTableDataChanged() {
074: SwingUtilities.invokeLater(new Runnable() {
075:
076: public void run() {
077: fireTableDataChanged();
078: }
079: });
080: }
081:
082: public Class getColumnClass(int column) {
083: return treeTableModel.getColumnClass(column);
084: }
085:
086: public int getColumnCount() {
087: return treeTableModel.getColumnCount();
088: }
089:
090: public String getColumnName(int column) {
091: return treeTableModel.getColumnName(column);
092: }
093:
094: public TreeTableBrowserDataModel getDataModel(int row, int column) {
095: return (TreeTableBrowserDataModel) treeTableModel.getValueAt(
096: nodeForRow(row), column);
097: }
098:
099: public int getRowCount() {
100: return tree.getRowCount();
101: }
102:
103: public String getToolTip(int row, int column) {
104: return ((TreeTableBrowserDataModel) treeTableModel.getValueAt(
105: nodeForRow(row), column)).getTooltip();
106: }
107:
108: public TreeTableBrowserModelInterface getTreeTableModel() {
109: return treeTableModel;
110: }
111:
112: public Object getValueAt(int row, int column) {
113: return treeTableModel.getValueAt(nodeForRow(row), column);
114: }
115:
116: public boolean isCellEditable(int row, int column) {
117: return treeTableModel.isCellEditable(nodeForRow(row), column);
118: }
119:
120: protected Object nodeForRow(int row) {
121: TreePath treePath = tree.getPathForRow(row);
122: return treePath != null ? treePath.getLastPathComponent()
123: : null;
124: }
125:
126: public void setTreeTableModel(
127: TreeTableBrowserModelInterface treeTableModel) {
128: this .treeTableModel = treeTableModel;
129: }
130:
131: public void setValueAt(Object value, int row, int column) {
132: treeTableModel.setValueAt(value, nodeForRow(row), column);
133: }
134:
135: public void sort() {
136: treeTableModel.sort();
137: }
138: }
|