001: package com.xoetrope.swing.treetable;
002:
003: import javax.swing.event.EventListenerList;
004: import javax.swing.event.TreeModelEvent;
005: import javax.swing.event.TreeModelListener;
006: import javax.swing.tree.TreePath;
007:
008: /**
009: * An abstract implementation of the TreeTableModel interface, handling the list
010: * of listeners.
011: * A tree node wrapper for an XModel node
012: *
013: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
014: * the GNU Public License (GPL), please see license.txt for more details. If
015: * you make commercial use of this software you must purchase a commercial
016: * license from Xoetrope.</p>
017: * <p> $Revision: 1.4 $</p>
018: */
019: public abstract class AbstractTreeTableModel implements TreeTableModel {
020: protected Object root;
021: protected EventListenerList listenerList = new EventListenerList();
022:
023: public AbstractTreeTableModel(Object root) {
024: this .root = root;
025: }
026:
027: //
028: // Default implmentations for methods in the TreeModel interface.
029: //
030:
031: public Object getRoot() {
032: return root;
033: }
034:
035: public boolean isLeaf(Object node) {
036: return getChildCount(node) == 0;
037: }
038:
039: public void valueForPathChanged(TreePath path, Object newValue) {
040: }
041:
042: // This is not called in the JTree's default mode: use a naive implementation.
043: public int getIndexOfChild(Object parent, Object child) {
044: for (int i = 0; i < getChildCount(parent); i++) {
045: if (getChild(parent, i).equals(child)) {
046: return i;
047: }
048: }
049: return -1;
050: }
051:
052: public void addTreeModelListener(TreeModelListener l) {
053: listenerList.add(TreeModelListener.class, l);
054: }
055:
056: public void removeTreeModelListener(TreeModelListener l) {
057: listenerList.remove(TreeModelListener.class, l);
058: }
059:
060: /*
061: * Notify all listeners that have registered interest for
062: * notification on this event type. The event instance
063: * is lazily created using the parameters passed into
064: * the fire method.
065: * @see EventListenerList
066: */
067: protected void fireTreeNodesChanged(Object source, Object[] path,
068: int[] childIndices, Object[] children) {
069: // Guaranteed to return a non-null array
070: Object[] listeners = listenerList.getListenerList();
071: TreeModelEvent e = null;
072: // Process the listeners last to first, notifying
073: // those that are interested in this event
074: for (int i = listeners.length - 2; i >= 0; i -= 2) {
075: if (listeners[i] == TreeModelListener.class) {
076: // Lazily create the event:
077: if (e == null)
078: e = new TreeModelEvent(source, path, childIndices,
079: children);
080: ((TreeModelListener) listeners[i + 1])
081: .treeNodesChanged(e);
082: }
083: }
084: }
085:
086: /*
087: * Notify all listeners that have registered interest for
088: * notification on this event type. The event instance
089: * is lazily created using the parameters passed into
090: * the fire method.
091: * @see EventListenerList
092: */
093: protected void fireTreeNodesInserted(Object source, Object[] path,
094: int[] childIndices, Object[] children) {
095: // Guaranteed to return a non-null array
096: Object[] listeners = listenerList.getListenerList();
097: TreeModelEvent e = null;
098: // Process the listeners last to first, notifying
099: // those that are interested in this event
100: for (int i = listeners.length - 2; i >= 0; i -= 2) {
101: if (listeners[i] == TreeModelListener.class) {
102: // Lazily create the event:
103: if (e == null)
104: e = new TreeModelEvent(source, path, childIndices,
105: children);
106: ((TreeModelListener) listeners[i + 1])
107: .treeNodesInserted(e);
108: }
109: }
110: }
111:
112: /*
113: * Notify all listeners that have registered interest for
114: * notification on this event type. The event instance
115: * is lazily created using the parameters passed into
116: * the fire method.
117: * @see EventListenerList
118: */
119: protected void fireTreeNodesRemoved(Object source, Object[] path,
120: int[] childIndices, Object[] children) {
121: // Guaranteed to return a non-null array
122: Object[] listeners = listenerList.getListenerList();
123: TreeModelEvent e = null;
124: // Process the listeners last to first, notifying
125: // those that are interested in this event
126: for (int i = listeners.length - 2; i >= 0; i -= 2) {
127: if (listeners[i] == TreeModelListener.class) {
128: // Lazily create the event:
129: if (e == null)
130: e = new TreeModelEvent(source, path, childIndices,
131: children);
132: ((TreeModelListener) listeners[i + 1])
133: .treeNodesRemoved(e);
134: }
135: }
136: }
137:
138: /*
139: * Notify all listeners that have registered interest for
140: * notification on this event type. The event instance
141: * is lazily created using the parameters passed into
142: * the fire method.
143: * @see EventListenerList
144: */
145: protected void fireTreeStructureChanged(Object source,
146: Object[] path, int[] childIndices, Object[] children) {
147: // Guaranteed to return a non-null array
148: Object[] listeners = listenerList.getListenerList();
149: TreeModelEvent e = null;
150: // Process the listeners last to first, notifying
151: // those that are interested in this event
152: for (int i = listeners.length - 2; i >= 0; i -= 2) {
153: if (listeners[i] == TreeModelListener.class) {
154: // Lazily create the event:
155: if (e == null)
156: e = new TreeModelEvent(source, path, childIndices,
157: children);
158: ((TreeModelListener) listeners[i + 1])
159: .treeStructureChanged(e);
160: }
161: }
162: }
163:
164: //
165: // Default impelmentations for methods in the TreeTableModel interface.
166: //
167:
168: public Class getColumnClass(int column) {
169: return Object.class;
170: }
171:
172: /** By default, make the column with the Tree in it the only editable one.
173: * Making this column editable causes the JTable to forward mouse
174: * and keyboard events in the Tree column to the underlying JTree.
175: */
176: public boolean isCellEditable(Object node, int column) {
177: return getColumnClass(column) == TreeTableModel.class;
178: }
179:
180: public void setValueAt(Object aValue, Object node, int column) {
181: }
182:
183: // Left to be implemented in the subclass:
184:
185: /*
186: * public Object getChild(Object parent, int index)
187: * public int getChildCount(Object parent)
188: * public int getColumnCount()
189: * public String getColumnName(Object node, int column)
190: * public Object getValueAt(Object node, int column)
191: */
192:
193: public abstract void reloadChildren(Object node);
194: }
|