KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > swing > treetable > AbstractTreeTableModel


1 /*
2  * $Id: AbstractTreeTableModel.java,v 1.3 2004/08/13 21:20:35 rameshgupta Exp $
3  *
4  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
5  * Santa Clara, California 95054, U.S.A. All rights reserved.
6  */

7
8 package org.jdesktop.swing.treetable;
9
10 import java.util.EventListener JavaDoc;
11
12 import javax.swing.event.EventListenerList JavaDoc;
13 import javax.swing.event.TreeModelEvent JavaDoc;
14 import javax.swing.event.TreeModelListener JavaDoc;
15 import javax.swing.tree.TreeNode JavaDoc;
16 import javax.swing.tree.TreePath JavaDoc;
17
18 // There is no javax.swing.tree.AbstractTreeModel; There ought to be one.
19

20 /**
21  * AbstractTreeTableModel provides an implementation of
22  * {@link org.jdesktop.swing.treetable.TreeTableModel} as a convenient starting
23  * point in defining custom data models for {@link org.jdesktop.swing.JXTreeTable}.
24  *
25  * @author Ramesh Gupta
26  */

27 public abstract class AbstractTreeTableModel implements TreeTableModel {
28     /**
29      * Value returned by {@link org.jdesktop.swing.treetable.TreeTableModel#getColumnClass(int) getColumnClass}
30      * for the {@link org.jdesktop.swing.JXTreeTable#isHierarchical(int) hierarchical} column.
31      */

32     public final static Class JavaDoc hierarchicalColumnClass = TreeTableModel.class;
33
34     /**
35      * Root node of the model
36      */

37     protected Object JavaDoc root;
38
39     /**
40      * Event listener list
41      */

42     protected EventListenerList JavaDoc listenerList = new EventListenerList JavaDoc();
43
44     /**
45      * Constructs an <code>AbstractTreeTableModel</code> with a null root node
46      */

47     public AbstractTreeTableModel() {
48         this(null);
49     }
50
51     /**
52      * Constructs an <code>AbstractTreeTableModel</code> with the specified node
53      * as the root node.
54      *
55      * @param root root node
56      */

57     public AbstractTreeTableModel(Object JavaDoc root) {
58         this.root = root;
59     }
60
61     /**
62      * {@inheritDoc}
63      */

64     public Class JavaDoc getColumnClass(int column) {
65         // Assume that the first column will contain hierarchical nodes.
66
return column == 0 ? hierarchicalColumnClass : Object JavaDoc.class;
67     }
68
69     /**
70      * {@inheritDoc}
71      */

72     public String JavaDoc getColumnName(int column) {
73         return "Column " + column; // Cheap implementation
74
}
75
76     /**
77      * {@inheritDoc}
78      */

79     public Object JavaDoc getRoot() { // From the TreeNode interface
80
return root;
81     }
82
83     /**
84      * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
85      * child array. <I>parent</I> must be a node previously obtained from
86      * this data source. This should not return null if <i>index</i>
87      * is a valid index for <i>parent</i> (that is <i>index</i> >= 0 &&
88      * <i>index</i> < getChildCount(<i>parent</i>)).
89      *
90      * @param parent a node in the tree, obtained from this data source
91      * @return the child of <I>parent</I> at index <I>index</I>, or null if the
92      * specified parent node is not a <code>TreeNode</code>.
93      */

94     public Object JavaDoc getChild(Object JavaDoc parent, int index) {
95         // meant to be overridden
96
try {
97             return ((TreeNode JavaDoc) parent).getChildAt(index);
98         }
99         catch (ClassCastException JavaDoc ex) { // not a TreeNode?
100
return null;
101         }
102     }
103
104     /**
105      * Returns the number of children in the specified parent node.
106      *
107      * @param parent node whose child count is being requested
108      * @return the number of children in the specified parent node
109      */

110     public int getChildCount(Object JavaDoc parent) {
111         // meant to be overridden
112
try {
113             return ((TreeNode JavaDoc) parent).getChildCount();
114         }
115         catch (ClassCastException JavaDoc ex) { // not a TreeNode?
116
return 0;
117         }
118     }
119
120     /**
121      * {@inheritDoc}
122      */

123     public int getColumnCount() {
124         // meant to be overridden
125
return 1; // Cheap (and woefully inadequate) implementation
126
}
127
128     /**
129      * Returns the index of child in parent.
130      * If either the parent or child is <code>null</code>, returns -1.
131      * @param parent a note in the tree, obtained from this data source
132      * @param child the node we are interested in
133      * @return the index of the child in the parent, or -1
134      * if either the parent or the child is <code>null</code>
135      */

136     public int getIndexOfChild(Object JavaDoc parent, Object JavaDoc child) {
137         if (parent == null || child == null)
138             return -1;
139
140         try {
141             return ((TreeNode JavaDoc) parent).getIndex((TreeNode JavaDoc) child);
142         }
143         catch (ClassCastException JavaDoc ex) { // not a TreeNode?
144
// This is not called in the JTree's default mode.
145
// Use a naive implementation.
146
for (int i = 0; i < getChildCount(parent); i++) {
147                 if (getChild(parent, i).equals(child)) {
148                     return i;
149                 }
150             }
151             return -1;
152         }
153     }
154
155     /**
156      * {@inheritDoc}
157      */

158     public boolean isCellEditable(Object JavaDoc node, int column) {
159         // RG: Fix Issue 49 -- Cell not editable, by default.
160
// Subclasses might override this to return true.
161
return false;
162     }
163
164     /**
165      * Returns true if the specified node is a leaf node; false otherwise.
166      *
167      * @param node node to test
168      * @return true if the specified node is a leaf node; false otherwise
169      */

170     public boolean isLeaf(Object JavaDoc node) {
171         try {
172             return ((TreeNode JavaDoc) node).isLeaf();
173         }
174         catch (ClassCastException JavaDoc ex) { // not a TreeNode?
175
return getChildCount(node) == 0;
176         }
177     }
178
179     /**
180      * Called when value for the item identified by path has been changed.
181      * If newValue signifies a truly new value the model should
182      * post a <code>treeNodesChanged</code> event.
183      *
184      * @param path path to the node that has changed
185      * @param newValue the new value from the <code>TreeCellEditor</code>
186      */

187     public void valueForPathChanged(TreePath JavaDoc path, Object JavaDoc newValue) {
188         /**@todo Implement this javax.swing.tree.TreeModel method*/
189     }
190
191     public void addTreeModelListener(TreeModelListener JavaDoc l) {
192         listenerList.add(TreeModelListener JavaDoc.class, l);
193     }
194
195     public void removeTreeModelListener(TreeModelListener JavaDoc l) {
196         listenerList.remove(TreeModelListener JavaDoc.class, l);
197     }
198
199     public TreeModelListener JavaDoc[] getTreeModelListeners() {
200         return (TreeModelListener JavaDoc[]) listenerList.getListeners(
201             TreeModelListener JavaDoc.class);
202     }
203
204     /*
205      * Notify all listeners that have registered interest for
206      * notification on this event type. The event instance
207      * is lazily created using the parameters passed into
208      * the fire method.
209      * @see EventListenerList
210      */

211     protected void fireTreeNodesChanged(Object JavaDoc source, Object JavaDoc[] path,
212                                         int[] childIndices, Object JavaDoc[] children) {
213         // Guaranteed to return a non-null array
214
Object JavaDoc[] listeners = listenerList.getListenerList();
215         TreeModelEvent JavaDoc e = null;
216         // Process the listeners last to first, notifying
217
// those that are interested in this event
218
for (int i = listeners.length - 2; i >= 0; i -= 2) {
219             if (listeners[i] == TreeModelListener JavaDoc.class) {
220                 // Lazily create the event:
221
if (e == null)
222                     e = new TreeModelEvent JavaDoc(source, path,
223                                            childIndices, children);
224                 ((TreeModelListener JavaDoc) listeners[i + 1]).treeNodesChanged(e);
225             }
226         }
227     }
228
229     /*
230      * Notify all listeners that have registered interest for
231      * notification on this event type. The event instance
232      * is lazily created using the parameters passed into
233      * the fire method.
234      * @see EventListenerList
235      */

236     protected void fireTreeNodesInserted(Object JavaDoc source, Object JavaDoc[] path,
237                                          int[] childIndices, Object JavaDoc[] children) {
238         // Guaranteed to return a non-null array
239
Object JavaDoc[] listeners = listenerList.getListenerList();
240         TreeModelEvent JavaDoc e = null;
241         // Process the listeners last to first, notifying
242
// those that are interested in this event
243
for (int i = listeners.length - 2; i >= 0; i -= 2) {
244             if (listeners[i] == TreeModelListener JavaDoc.class) {
245                 // Lazily create the event:
246
if (e == null)
247                     e = new TreeModelEvent JavaDoc(source, path,
248                                            childIndices, children);
249                 ((TreeModelListener JavaDoc) listeners[i + 1]).treeNodesInserted(e);
250             }
251         }
252     }
253
254     /*
255      * Notify all listeners that have registered interest for
256      * notification on this event type. The event instance
257      * is lazily created using the parameters passed into
258      * the fire method.
259      * @see EventListenerList
260      */

261     protected void fireTreeNodesRemoved(Object JavaDoc source, Object JavaDoc[] path,
262                                         int[] childIndices, Object JavaDoc[] children) {
263         // Guaranteed to return a non-null array
264
Object JavaDoc[] listeners = listenerList.getListenerList();
265         TreeModelEvent JavaDoc e = null;
266         // Process the listeners last to first, notifying
267
// those that are interested in this event
268
for (int i = listeners.length - 2; i >= 0; i -= 2) {
269             if (listeners[i] == TreeModelListener JavaDoc.class) {
270                 // Lazily create the event:
271
if (e == null)
272                     e = new TreeModelEvent JavaDoc(source, path,
273                                            childIndices, children);
274                 ((TreeModelListener JavaDoc) listeners[i + 1]).treeNodesRemoved(e);
275             }
276         }
277     }
278
279     /*
280      * Notify all listeners that have registered interest for
281      * notification on this event type. The event instance
282      * is lazily created using the parameters passed into
283      * the fire method.
284      * @see EventListenerList
285      */

286     protected void fireTreeStructureChanged(Object JavaDoc source, Object JavaDoc[] path,
287                                             int[] childIndices,
288                                             Object JavaDoc[] children) {
289         // Guaranteed to return a non-null array
290
Object JavaDoc[] listeners = listenerList.getListenerList();
291         TreeModelEvent JavaDoc e = null;
292         // Process the listeners last to first, notifying
293
// those that are interested in this event
294
for (int i = listeners.length - 2; i >= 0; i -= 2) {
295             if (listeners[i] == TreeModelListener JavaDoc.class) {
296                 // Lazily create the event:
297
if (e == null) {
298                     e = new TreeModelEvent JavaDoc(source, path,
299                                            childIndices, children);
300                 }
301                 ((TreeModelListener JavaDoc) listeners[i + 1]).treeStructureChanged(e);
302             }
303         }
304     }
305
306     /**
307      * Returns an array of all the objects currently registered
308      * as <code><em>Foo</em>Listener</code>s
309      * upon this model.
310      * <code><em>Foo</em>Listener</code>s are registered using the
311      * <code>add<em>Foo</em>Listener</code> method.
312      *
313      * <p>
314      *
315      * You can specify the <code>listenerType</code> argument
316      * with a class literal,
317      * such as
318      * <code><em>Foo</em>Listener.class</code>.
319      * For example, you can query a
320      * <code>DefaultTreeModel</code> <code>m</code>
321      * for its tree model listeners with the following code:
322      *
323      * <pre>TreeModelListener[] tmls = (TreeModelListener[])(m.getListeners(TreeModelListener.class));</pre>
324      *
325      * If no such listeners exist, this method returns an empty array.
326      *
327      * @param listenerType the type of listeners requested; this parameter
328      * should specify an interface that descends from
329      * <code>java.util.EventListener</code>
330      * @return an array of all objects registered as
331      * <code><em>Foo</em>Listener</code>s on this component,
332      * or an empty array if no such
333      * listeners have been added
334      * @exception ClassCastException if <code>listenerType</code>
335      * doesn't specify a class or interface that implements
336      * <code>java.util.EventListener</code>
337      *
338      * @see #getTreeModelListeners
339      *
340      * @since 1.3
341      */

342     public EventListener JavaDoc[] getListeners(Class JavaDoc listenerType) {
343         return listenerList.getListeners(listenerType);
344     }
345
346     // Left to be implemented in the subclass:
347

348     /**
349      * public Object getChild(Object parent, int index)
350      * public int getChildCount(Object parent)
351      * public int getColumnCount()
352      * public String getColumnName(int column)
353      * public Object getValueAt(Object node, int column)
354      * public void setValueAt(Object value, Object node, int column)
355      */

356 }
357
Popular Tags