1. /*
  2. * @(#)TreeModelEvent.java 1.23 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.event;
  8. import java.util.EventObject;
  9. import javax.swing.tree.TreePath;
  10. /**
  11. * Encapsulates information describing changes to a tree model, and
  12. * used to notify tree model listeners of the change.
  13. * <p>
  14. * <strong>Warning:</strong>
  15. * Serialized objects of this class will not be compatible with
  16. * future Swing releases. The current serialization support is appropriate
  17. * for short term storage or RMI between applications running the same
  18. * version of Swing. A future release of Swing will provide support for
  19. * long term persistence.
  20. *
  21. * @version 1.23 11/29/01
  22. * @author Rob Davis
  23. * @author Ray Ryan
  24. * @author Scott Violet
  25. */
  26. public class TreeModelEvent extends EventObject {
  27. /** Path to the parent of the nodes that have changed. */
  28. protected TreePath path;
  29. /** Indices identifying the position of where the children were. */
  30. protected int[] childIndices;
  31. /** Children that have been removed. */
  32. protected Object[] children;
  33. /**
  34. * Used to create an event when nodes have been changed, inserted, or
  35. * removed, identifying the path to the parent of the modified items as
  36. * an array of Objects. All of the modified objects are siblings which are
  37. * direct descendents (not grandchildren) of the specified parent.
  38. * The positions at which the inserts, deletes, or changes occured are
  39. * specified by an array of <code>int</code>. The indexes in that array
  40. * must be in order, from lowest to highest.
  41. * <p>
  42. * For changes, the indexes in the model correspond exactly to the indexes
  43. * of items currently displayed in the UI. As a result, it is not really
  44. * critical if the indexes are not in their exact order. But after multiple
  45. * inserts or deletes, the items currently in the UI no longer correspond
  46. * to the items in the model. It is therefore critical to specify the
  47. * indexes properly for inserts and deletes.
  48. * <p>
  49. * For inserts, the indexes represent the <i>final</i> state of the tree,
  50. * after the inserts have occurred. Since the indexes must be specified in
  51. * order, the most natural processing methodology is to do the inserts
  52. * starting at the lowest index and working towards the highest. Accumulate
  53. * a Vector of <code>Integer</code> objects that specify the
  54. * insert-locations as you go, then convert the Vector to an
  55. * array of <code>int</code> to create the event. When the postition-index
  56. * equals zero, the node is inserted at the beginning of the list. When the
  57. * position index equals the size of the list, the node is "inserted" at
  58. * (appended to) the end of the list.
  59. * <p>
  60. * For deletes, the indexes represent the <i>initial</i> state of the tree,
  61. * before the deletes have occurred. Since the indexes must be specified in
  62. * order, the most natural processing methodology is to use a delete-counter.
  63. * Start by initializing the counter to zero and start work through the
  64. * list from lowest to higest. Every time you do a delete, add the current
  65. * value of the delete-counter to the index-position where the delete occurred,
  66. * and append the result to a Vector of delete-locations, using
  67. * <code>addElement()</code>. Then increment the delete-counter. The index
  68. * positions stored in the Vector therefore reflect the effects of all previous
  69. * deletes, so they represent each object's position in the initial tree.
  70. * (You could also start at the highest index and working back towards the
  71. * lowest, accumulating a Vector of delete-locations as you go using the
  72. * <code>insertElementAt(Integer, 0)</code>.) However you produce the Vector
  73. * of initial-positions, you then need to convert the Vector of <code>Integer</code>
  74. * objects to an array of <code>int</code> to create the event.
  75. * <p>
  76. * <b>Notes:</b><ul>
  77. * <li>Like the <code>insertNodeInto</code> method in the
  78. * <code>DefaultTreeModel</code> class, <code>insertElementAt</code>
  79. * appends to the <code>Vector</code> when the index matches the size
  80. * of the vector. So you can use <code>insertElementAt(Integer, 0)</code>
  81. * even when the vector is empty.
  82. * <ul>To create a node changed event for the root node, specify the parent
  83. * as null and the "child" index as zero.
  84. * </ul>
  85. *
  86. * @param source the Object responsible for generating the event (typically
  87. * the creator of the event object passes <code>this</code>
  88. * for its value)
  89. * @param path an array of Object identifying the path to the
  90. * parent of the modified item(s), where the first element
  91. * of the array is the Object stored at the root node and
  92. * the last element is the Object stored at the parent node
  93. * @param childIndices an array of <code>int</code> that specifies the
  94. * index values of the removed items. The indices must be
  95. * in sorted order, from lowest to highest
  96. * @param children an array of Object containing the inserted, removed, or
  97. * changed objects
  98. * @see TreePath
  99. */
  100. public TreeModelEvent(Object source, Object[] path, int[] childIndices,
  101. Object[] children)
  102. {
  103. this(source, new TreePath(path), childIndices, children);
  104. }
  105. /**
  106. * Used to create an event when nodes have been changed, inserted, or
  107. * removed, identifying the path to the parent of the modified items as
  108. * a TreePath object. For more information on how to specify the indexes
  109. * and objects, see
  110. * <code>TreeModelEvent(Object,Object[],int[],Object[])</code>.
  111. *
  112. * @param source the Object responsible for generating the event (typically
  113. * the creator of the event object passes <code>this</code>
  114. * for its value)
  115. * @param path a TreePath object that identifies the path to the
  116. * parent of the modified item(s)
  117. * @param childIndices an array of <code>int</code> that specifies the
  118. * index values of the modified items
  119. * @param children an array of Object containing the inserted, removed, or
  120. * changed objects
  121. *
  122. * @see #TreeModelEvent(Object,Object[],int[],Object[])
  123. */
  124. public TreeModelEvent(Object source, TreePath path, int[] childIndices,
  125. Object[] children)
  126. {
  127. super(source);
  128. this.path = path;
  129. this.childIndices = childIndices;
  130. this.children = children;
  131. }
  132. /**
  133. * Used to create an event when the node structure has changed in some way,
  134. * identifying the path to the root of a modified subtree as an array of
  135. * Objects. A structure change event might involve nodes swapping position,
  136. * for example, or it might encapsulate multiple inserts and deletes in the
  137. * subtree stemming from the node, where the changes may have taken place at
  138. * different levels of the subtree.
  139. * <blockquote>
  140. * <b>Note:</b><br>
  141. * JTree collapses all nodes under the specified node, so that only its
  142. * immediate children are visible.
  143. * </blockquote>
  144. *
  145. * @param source the Object responsible for generating the event (typically
  146. * the creator of the event object passes <code>this</code>
  147. * for its value)
  148. * @param path an array of Object identifying the path to the root of the
  149. * modified subtree, where the first element of the array is
  150. * the object stored at the root node and the last element
  151. * is the object stored at the changed node
  152. * @see TreePath
  153. */
  154. public TreeModelEvent(Object source, Object[] path)
  155. {
  156. this(source, new TreePath(path));
  157. }
  158. /**
  159. * Used to create an event when the node structure has changed in some way,
  160. * identifying the path to the root of the modified subtree as a TreePath
  161. * object. For more information on this event specification, see
  162. * <code>TreeModelEvent(Object,Object[])</code>.
  163. *
  164. * @param source the Object responsible for generating the event (typically
  165. * the creator of the event object passes <code>this</code>
  166. * for its value)
  167. * @param path a TreePath object that identifies the path to the
  168. * change. In the DefaultTreeModel,
  169. * this object contains an array of user-data objects,
  170. * but a subclass of TreePath could use some totally
  171. * different mechanism -- for example, a node ID number
  172. *
  173. * @see #TreeModelEvent(Object,Object[])
  174. */
  175. public TreeModelEvent(Object source, TreePath path)
  176. {
  177. super(source);
  178. this.path = path;
  179. this.childIndices = new int[0];
  180. }
  181. /**
  182. * Returns the TreePath object identifying the changed node.
  183. * Use <code>getLastPathComponent</code> on that object to
  184. * get the data stored at that node.
  185. *
  186. * @return the TreePath object identifying the changed node
  187. * @see TreePath#getLastPathComponent
  188. */
  189. public TreePath getTreePath() { return path; }
  190. /**
  191. * Convenience method to get the array of objects from the TreePath
  192. * instance that this event wraps.
  193. *
  194. * @return an array of Objects, where the first Object is the one
  195. * stored at the root and the last object is the one
  196. * stored at the node identified by the path
  197. */
  198. public Object[] getPath() {
  199. if(path != null)
  200. return path.getPath();
  201. return null;
  202. }
  203. /**
  204. * Returns the objects that are children of the node identified by
  205. * <code>getPath</code> at the locations specified by
  206. * <code>getChildIndices</code>. If this is a removal event the
  207. * returned objects are no longer children of the parent node.
  208. *
  209. * @return an array of Object containing the children specified by
  210. * the event
  211. * @see #getPath
  212. * @see #getChildIndices
  213. */
  214. public Object[] getChildren() {
  215. if(children != null) {
  216. int cCount = children.length;
  217. Object[] retChildren = new Object[cCount];
  218. System.arraycopy(children, 0, retChildren, 0, cCount);
  219. return retChildren;
  220. }
  221. return null;
  222. }
  223. /**
  224. * Returns the values of the child indexes. If this is a removal event
  225. * the indexes point to locations in the initial list where items
  226. * were removed. If it is an insert, the indices point to locations
  227. * in the final list where the items were added. For node changes,
  228. * the indices point to the locations of the modified nodes.
  229. *
  230. * @return an array of <code>int</code> containing index locations for
  231. * the children specified by the event
  232. */
  233. public int[] getChildIndices() {
  234. if(childIndices != null) {
  235. int cCount = childIndices.length;
  236. int[] retArray = new int[cCount];
  237. System.arraycopy(childIndices, 0, retArray, 0, cCount);
  238. return retArray;
  239. }
  240. return null;
  241. }
  242. /**
  243. * Returns a string that displays and identifies this object's
  244. * properties.
  245. *
  246. * @return a String representation of this object
  247. */
  248. public String toString() {
  249. StringBuffer retBuffer = new StringBuffer();
  250. retBuffer.append(getClass().getName() + " " +
  251. Integer.toString(hashCode()));
  252. if(path != null)
  253. retBuffer.append(" path " + path);
  254. if(childIndices != null) {
  255. retBuffer.append(" indicices [ ");
  256. for(int counter = 0; counter < childIndices.length; counter++)
  257. retBuffer.append(Integer.toString(childIndices[counter])+ " ");
  258. retBuffer.append("]");
  259. }
  260. if(children != null) {
  261. retBuffer.append(" children [ ");
  262. for(int counter = 0; counter < children.length; counter++)
  263. retBuffer.append(children[counter] + " ");
  264. retBuffer.append("]");
  265. }
  266. return retBuffer.toString();
  267. }
  268. }