Merge from mainline
[official-gcc.git] / libjava / classpath / javax / swing / tree / DefaultTreeModel.java
blob818f548a78d591079f266eb351347c9b3db616df
1 /* DefaultTreeModel.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package javax.swing.tree;
40 import java.io.IOException;
41 import java.io.ObjectInputStream;
42 import java.io.ObjectOutputStream;
43 import java.io.Serializable;
44 import java.util.EventListener;
46 import javax.swing.event.EventListenerList;
47 import javax.swing.event.TreeModelEvent;
48 import javax.swing.event.TreeModelListener;
49 import javax.swing.tree.DefaultMutableTreeNode;
51 /**
52 * DefaultTreeModel
54 * @author Andrew Selkirk
56 public class DefaultTreeModel
57 implements Serializable, TreeModel
59 static final long serialVersionUID = -2621068368932566998L;
61 /**
62 * root
64 protected TreeNode root = null;
66 /**
67 * listenerList
69 protected EventListenerList listenerList = new EventListenerList();
71 /**
72 * asksAllowsChildren
74 protected boolean asksAllowsChildren;
76 /**
77 * Constructor DefaultTreeModel
79 * @param root the tree root.
81 public DefaultTreeModel(TreeNode root)
83 if (root == null)
84 root = new DefaultMutableTreeNode();
85 setRoot(root);
88 /**
89 * Constructor DefaultTreeModel
91 * @param root the tree root.
92 * @param asksAllowsChildren TODO
94 public DefaultTreeModel(TreeNode root, boolean asksAllowsChildren)
96 setRoot(root);
97 this.asksAllowsChildren = asksAllowsChildren;
101 * writeObject
103 * @param obj the object.
104 * @exception IOException TODO
106 private void writeObject(ObjectOutputStream obj) throws IOException
108 // TODO
112 * readObject
114 * @param value0 TODO
115 * @exception IOException TODO
116 * @exception ClassNotFoundException TODO
118 private void readObject(ObjectInputStream value0) throws IOException,
119 ClassNotFoundException
121 // TODO
125 * asksAllowsChildren
127 * @return boolean
129 public boolean asksAllowsChildren()
131 return asksAllowsChildren;
135 * setAsksAllowsChildren
137 * @param value TODO
139 public void setAsksAllowsChildren(boolean value)
141 asksAllowsChildren = value;
145 * setRoot
147 * @param root the root node.
149 public void setRoot(TreeNode root)
151 this.root = root;
155 * getRoot
157 * @return Object
159 public Object getRoot()
161 return root;
165 * getIndexOfChild
167 * @param parent TODO
168 * @param child TODO
169 * @return int
171 public int getIndexOfChild(Object parent, Object child)
173 for (int i = 0; i < getChildCount(parent); i++)
175 if (getChild(parent, i).equals(child))
176 return i;
178 return -1;
182 * getChild
184 * @param node TODO
185 * @param idx TODO
186 * @return Object
188 public Object getChild(Object node, int idx)
190 if (node instanceof TreeNode)
191 return ((TreeNode) node).getChildAt(idx);
192 else
193 return null;
197 * getChildCount
199 * @param node TODO
200 * @return int
202 public int getChildCount(Object node)
204 if (node instanceof TreeNode)
205 return ((TreeNode) node).getChildCount();
206 else
207 return 0;
211 * isLeaf
213 * @param node TODO
214 * @return boolean
216 public boolean isLeaf(Object node)
218 if (node instanceof TreeNode)
219 return ((TreeNode) node).isLeaf();
220 else
221 return true;
225 * Invoke this method if you've modified the TreeNodes upon
226 * which this model depends. The model will notify all of its
227 * listeners that the model has changed.
229 public void reload()
231 // TODO
235 * Invoke this method if you've modified the TreeNodes upon
236 * which this model depends. The model will notify all of its
237 * listeners that the model has changed.
239 * @param node - TODO
241 public void reload(TreeNode node)
243 // TODO
247 * Messaged when the user has altered the value for the item
248 * identified by path to newValue. If newValue signifies a truly new
249 * value the model should post a treeNodesChanged event.
250 * This sets the user object of the TreeNode identified by
251 * path and posts a node changed. If you use custom user objects
252 * in the TreeModel you're going to need to subclass this and set
253 * the user object of the changed node to something meaningful.
255 * @param path - path to the node that the user has altered
256 * @param newValue - the new value from the TreeCellEditor
258 public void valueForPathChanged(TreePath path, Object newValue)
260 Object node = path.getLastPathComponent();
261 if (node instanceof MutableTreeNode)
263 ((MutableTreeNode) node).setUserObject(newValue);
264 int[] ci = null;
265 Object[] c = null;
266 Object[] parentPath = path.getPath();
267 if (path.getPathCount() > 1)
269 Object parent = ((TreeNode) node).getParent();
270 ci = new int[1];
271 ci[0] = getIndexOfChild(parent, node);
272 node = newValue;
273 path = path.getParentPath().pathByAddingChild(node);
274 c = new Object[1];
275 c[0] = node;
276 parentPath = path.getParentPath().getPath();
279 fireTreeNodesChanged(this, parentPath, ci, c);
284 * Invoked this to insert newChild at location index in parents children.
285 * This will then message nodesWereInserted to create the appropriate event.
286 * This is the preferred way to add children as it will create the
287 * appropriate event.
289 * @param newChild is the node to add to the parent's children
290 * @param parent is the parent of the newChild
291 * @param index is the index of the newChild
293 public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent,
294 int index)
296 newChild.setParent(parent);
297 parent.insert(newChild, index);
298 int[] childIndices = new int[1];
299 childIndices[0] = index;
300 nodesWereInserted(parent, childIndices);
304 * Message this to remove node from its parent. This will message
305 * nodesWereRemoved to create the appropriate event. This is the preferred
306 * way to remove a node as it handles the event creation for you.
308 * @param node to be removed
310 public void removeNodeFromParent(MutableTreeNode node)
312 TreeNode parent = node.getParent();
313 Object[] children = new Object[1];
314 children[0] = node;
315 int[] childIndices = new int[1];
316 childIndices[0] = getIndexOfChild(parent, node);
317 node.removeFromParent();
318 nodesWereRemoved(parent, childIndices, children);
322 * Invoke this method after you've changed how node is to be represented
323 * in the tree.
325 * @param node that was changed
327 public void nodeChanged(TreeNode node)
329 TreeNode parent = node.getParent();
330 int[] childIndices = new int[1];
331 childIndices[0] = getIndexOfChild(parent, node);
332 Object[] children = new Object[1];
333 children[0] = node;
334 fireTreeNodesChanged(this, getPathToRoot(node), childIndices, children);
338 * Invoke this method after you've inserted some TreeNodes
339 * into node. childIndices should be the index of the new elements and must
340 * be sorted in ascending order.
342 * @param parent that had a child added to
343 * @param childIndices of the children added
345 public void nodesWereInserted(TreeNode parent, int[] childIndices)
347 Object[] children = new Object[childIndices.length];
348 for (int i = 0; i < children.length; i++)
349 children[i] = getChild(parent, childIndices[i]);
350 fireTreeNodesInserted(this, getPathToRoot(parent), childIndices, children);
354 * Invoke this method after you've removed some TreeNodes from node.
355 * childIndices should be the index of the removed elements and
356 * must be sorted in ascending order. And removedChildren should be the
357 * array of the children objects that were removed.
359 * @param parent that had a child added to
360 * @param childIndices of the children added
361 * @param removedChildren are all the children removed from parent.
363 public void nodesWereRemoved(TreeNode parent, int[] childIndices,
364 Object[] removedChildren)
366 fireTreeNodesRemoved(this, getPathToRoot(parent), childIndices,
367 removedChildren);
371 * Invoke this method after you've changed how the children identified by
372 * childIndices are to be represented in the tree.
374 * @param node that is the parent of the children that changed in a tree.
375 * @param childIndices are the child nodes that changed.
377 public void nodesChanged(TreeNode node, int[] childIndices)
379 Object[] children = new Object[childIndices.length];
380 for (int i = 0; i < children.length; i++)
381 children[i] = getChild(node, childIndices[i]);
382 fireTreeNodesChanged(this, getPathToRoot(node), childIndices, children);
386 * Invoke this method if you've totally changed the children of node and
387 * its childrens children. This will post a treeStructureChanged event.
389 * @param node that had its children and grandchildren changed.
391 public void nodeStructureChanged(TreeNode node)
393 // TODO
397 * Builds the parents of node up to and including the root node, where
398 * the original node is the last element in the returned array. The
399 * length of the returned array gives the node's depth in the tree.
401 * @param node - the TreeNode to get the path for
402 * @return TreeNode[] - the path from node to the root
404 public TreeNode[] getPathToRoot(TreeNode node)
406 return getPathToRoot(node, 0);
410 * Builds the parents of node up to and including the root node, where
411 * the original node is the last element in the returned array. The
412 * length of the returned array gives the node's depth in the tree.
414 * @param node - the TreeNode to get the path for
415 * @param depth - an int giving the number of steps already taken
416 * towards the root (on recursive calls), used to size the returned array
417 * @return an array of TreeNodes giving the path from the root to the
418 * specified node
420 protected TreeNode[] getPathToRoot(TreeNode node, int depth)
422 if (node == null)
424 if (depth == 0)
425 return null;
427 return new TreeNode[depth];
430 TreeNode[] path = getPathToRoot(node.getParent(), depth + 1);
431 path[path.length - depth - 1] = node;
432 return path;
436 * Registers a listere to the model.
438 * @param listener the listener to add
440 public void addTreeModelListener(TreeModelListener listener)
442 listenerList.add(TreeModelListener.class, listener);
446 * Removes a listener from the model.
448 * @param listener the listener to remove
450 public void removeTreeModelListener(TreeModelListener listener)
452 listenerList.remove(TreeModelListener.class, listener);
456 * Returns all registered <code>TreeModelListener</code> listeners.
458 * @return an array of listeners.
460 * @since 1.4
462 public TreeModelListener[] getTreeModelListeners()
464 return (TreeModelListener[]) listenerList
465 .getListeners(TreeModelListener.class);
469 * Notifies all listeners that have registered interest for notification
470 * on this event type. The event instance is lazily created using the parameters
471 * passed into the fire method.
473 * @param source the node being changed
474 * @param path the path to the root node
475 * @param childIndices the indices of the changed elements
476 * @param children the changed elements
478 protected void fireTreeNodesChanged(Object source, Object[] path,
479 int[] childIndices, Object[] children)
481 TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
482 children);
484 TreeModelListener[] listeners = getTreeModelListeners();
486 for (int i = listeners.length - 1; i >= 0; --i)
487 listeners[i].treeNodesChanged(event);
491 * fireTreeNodesInserted
493 * @param source the node where new nodes got inserted
494 * @param path the path to the root node
495 * @param childIndices the indices of the new elements
496 * @param children the new elements
498 protected void fireTreeNodesInserted(Object source, Object[] path,
499 int[] childIndices, Object[] children)
501 TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
502 children);
503 TreeModelListener[] listeners = getTreeModelListeners();
505 for (int i = listeners.length - 1; i >= 0; --i)
506 listeners[i].treeNodesInserted(event);
510 * fireTreeNodesRemoved
512 * @param source the node where nodes got removed-
513 * @param path the path to the root node
514 * @param childIndices the indices of the removed elements
515 * @param children the removed elements
517 protected void fireTreeNodesRemoved(Object source, Object[] path,
518 int[] childIndices, Object[] children)
520 TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
521 children);
522 TreeModelListener[] listeners = getTreeModelListeners();
524 for (int i = listeners.length - 1; i >= 0; --i)
525 listeners[i].treeNodesRemoved(event);
529 * fireTreeStructureChanged
531 * @param source the node where the model has changed
532 * @param path the path to the root node
533 * @param childIndices the indices of the affected elements
534 * @param children the affected elements
536 protected void fireTreeStructureChanged(Object source, Object[] path,
537 int[] childIndices, Object[] children)
539 TreeModelEvent event = new TreeModelEvent(source, path, childIndices,
540 children);
541 TreeModelListener[] listeners = getTreeModelListeners();
543 for (int i = listeners.length - 1; i >= 0; --i)
544 listeners[i].treeStructureChanged(event);
548 * Returns the registered listeners of a given type.
550 * @param listenerType the listener type to return
552 * @return an array of listeners
554 * @since 1.3
556 public EventListener[] getListeners(Class listenerType)
558 return listenerList.getListeners(listenerType);