Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/share/classes/javax/swing/tree/DefaultTreeModel.java
+++ new/src/share/classes/javax/swing/tree/DefaultTreeModel.java
1 1 /*
2 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
26 26 package javax.swing.tree;
27 27
28 28 import java.util.*;
29 29 import java.beans.ConstructorProperties;
30 30 import java.io.*;
31 31 import javax.swing.event.*;
32 32
33 33 /**
34 34 * A simple tree data model that uses TreeNodes.
35 35 * For further information and examples that use DefaultTreeModel,
36 - * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
36 + * see <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html">How to Use Trees</a>
37 37 * in <em>The Java Tutorial.</em>
38 38 * <p>
39 39 * <strong>Warning:</strong>
40 40 * Serialized objects of this class will not be compatible with
41 41 * future Swing releases. The current serialization support is
42 42 * appropriate for short term storage or RMI between applications running
43 43 * the same version of Swing. As of 1.4, support for long term storage
44 44 * of all JavaBeans™
45 45 * has been added to the <code>java.beans</code> package.
46 46 * Please see {@link java.beans.XMLEncoder}.
47 47 *
48 48 * @author Rob Davis
49 49 * @author Ray Ryan
50 50 * @author Scott Violet
51 51 */
52 52 public class DefaultTreeModel implements Serializable, TreeModel {
53 53 /** Root of the tree. */
54 54 protected TreeNode root;
55 55 /** Listeners. */
56 56 protected EventListenerList listenerList = new EventListenerList();
57 57 /**
58 58 * Determines how the <code>isLeaf</code> method figures
59 59 * out if a node is a leaf node. If true, a node is a leaf
60 60 * node if it does not allow children. (If it allows
61 61 * children, it is not a leaf node, even if no children
62 62 * are present.) That lets you distinguish between <i>folder</i>
63 63 * nodes and <i>file</i> nodes in a file system, for example.
64 64 * <p>
65 65 * If this value is false, then any node which has no
66 66 * children is a leaf node, and any node may acquire
67 67 * children.
68 68 *
69 69 * @see TreeNode#getAllowsChildren
70 70 * @see TreeModel#isLeaf
71 71 * @see #setAsksAllowsChildren
72 72 */
73 73 protected boolean asksAllowsChildren;
74 74
75 75
76 76 /**
77 77 * Creates a tree in which any node can have children.
78 78 *
79 79 * @param root a TreeNode object that is the root of the tree
80 80 * @see #DefaultTreeModel(TreeNode, boolean)
81 81 */
82 82 @ConstructorProperties({"root"})
83 83 public DefaultTreeModel(TreeNode root) {
84 84 this(root, false);
85 85 }
86 86
87 87 /**
88 88 * Creates a tree specifying whether any node can have children,
89 89 * or whether only certain nodes can have children.
90 90 *
91 91 * @param root a TreeNode object that is the root of the tree
92 92 * @param asksAllowsChildren a boolean, false if any node can
93 93 * have children, true if each node is asked to see if
94 94 * it can have children
95 95 * @see #asksAllowsChildren
96 96 */
97 97 public DefaultTreeModel(TreeNode root, boolean asksAllowsChildren) {
98 98 super();
99 99 this.root = root;
100 100 this.asksAllowsChildren = asksAllowsChildren;
101 101 }
102 102
103 103 /**
104 104 * Sets whether or not to test leafness by asking getAllowsChildren()
105 105 * or isLeaf() to the TreeNodes. If newvalue is true, getAllowsChildren()
106 106 * is messaged, otherwise isLeaf() is messaged.
107 107 */
108 108 public void setAsksAllowsChildren(boolean newValue) {
109 109 asksAllowsChildren = newValue;
110 110 }
111 111
112 112 /**
113 113 * Tells how leaf nodes are determined.
114 114 *
115 115 * @return true if only nodes which do not allow children are
116 116 * leaf nodes, false if nodes which have no children
117 117 * (even if allowed) are leaf nodes
118 118 * @see #asksAllowsChildren
119 119 */
120 120 public boolean asksAllowsChildren() {
121 121 return asksAllowsChildren;
122 122 }
123 123
124 124 /**
125 125 * Sets the root to <code>root</code>. A null <code>root</code> implies
126 126 * the tree is to display nothing, and is legal.
127 127 */
128 128 public void setRoot(TreeNode root) {
129 129 Object oldRoot = this.root;
130 130 this.root = root;
131 131 if (root == null && oldRoot != null) {
132 132 fireTreeStructureChanged(this, null);
133 133 }
134 134 else {
135 135 nodeStructureChanged(root);
136 136 }
137 137 }
138 138
139 139 /**
140 140 * Returns the root of the tree. Returns null only if the tree has
141 141 * no nodes.
142 142 *
143 143 * @return the root of the tree
144 144 */
145 145 public Object getRoot() {
146 146 return root;
147 147 }
148 148
149 149 /**
150 150 * Returns the index of child in parent.
151 151 * If either the parent or child is <code>null</code>, returns -1.
152 152 * @param parent a note in the tree, obtained from this data source
153 153 * @param child the node we are interested in
154 154 * @return the index of the child in the parent, or -1
155 155 * if either the parent or the child is <code>null</code>
156 156 */
157 157 public int getIndexOfChild(Object parent, Object child) {
158 158 if(parent == null || child == null)
159 159 return -1;
160 160 return ((TreeNode)parent).getIndex((TreeNode)child);
161 161 }
162 162
163 163 /**
164 164 * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
165 165 * child array. <I>parent</I> must be a node previously obtained from
166 166 * this data source. This should not return null if <i>index</i>
167 167 * is a valid index for <i>parent</i> (that is <i>index</i> >= 0 &&
168 168 * <i>index</i> < getChildCount(<i>parent</i>)).
169 169 *
170 170 * @param parent a node in the tree, obtained from this data source
171 171 * @return the child of <I>parent</I> at index <I>index</I>
172 172 */
173 173 public Object getChild(Object parent, int index) {
174 174 return ((TreeNode)parent).getChildAt(index);
175 175 }
176 176
177 177 /**
178 178 * Returns the number of children of <I>parent</I>. Returns 0 if the node
179 179 * is a leaf or if it has no children. <I>parent</I> must be a node
180 180 * previously obtained from this data source.
181 181 *
182 182 * @param parent a node in the tree, obtained from this data source
183 183 * @return the number of children of the node <I>parent</I>
184 184 */
185 185 public int getChildCount(Object parent) {
186 186 return ((TreeNode)parent).getChildCount();
187 187 }
188 188
189 189 /**
190 190 * Returns whether the specified node is a leaf node.
191 191 * The way the test is performed depends on the
192 192 * <code>askAllowsChildren</code> setting.
193 193 *
194 194 * @param node the node to check
195 195 * @return true if the node is a leaf node
196 196 *
197 197 * @see #asksAllowsChildren
198 198 * @see TreeModel#isLeaf
199 199 */
200 200 public boolean isLeaf(Object node) {
201 201 if(asksAllowsChildren)
202 202 return !((TreeNode)node).getAllowsChildren();
203 203 return ((TreeNode)node).isLeaf();
204 204 }
205 205
206 206 /**
207 207 * Invoke this method if you've modified the {@code TreeNode}s upon which
208 208 * this model depends. The model will notify all of its listeners that the
209 209 * model has changed.
210 210 */
211 211 public void reload() {
212 212 reload(root);
213 213 }
214 214
215 215 /**
216 216 * This sets the user object of the TreeNode identified by path
217 217 * and posts a node changed. If you use custom user objects in
218 218 * the TreeModel you're going to need to subclass this and
219 219 * set the user object of the changed node to something meaningful.
220 220 */
221 221 public void valueForPathChanged(TreePath path, Object newValue) {
222 222 MutableTreeNode aNode = (MutableTreeNode)path.getLastPathComponent();
223 223
224 224 aNode.setUserObject(newValue);
225 225 nodeChanged(aNode);
226 226 }
227 227
228 228 /**
229 229 * Invoked this to insert newChild at location index in parents children.
230 230 * This will then message nodesWereInserted to create the appropriate
231 231 * event. This is the preferred way to add children as it will create
232 232 * the appropriate event.
233 233 */
234 234 public void insertNodeInto(MutableTreeNode newChild,
235 235 MutableTreeNode parent, int index){
236 236 parent.insert(newChild, index);
237 237
238 238 int[] newIndexs = new int[1];
239 239
240 240 newIndexs[0] = index;
241 241 nodesWereInserted(parent, newIndexs);
242 242 }
243 243
244 244 /**
245 245 * Message this to remove node from its parent. This will message
246 246 * nodesWereRemoved to create the appropriate event. This is the
247 247 * preferred way to remove a node as it handles the event creation
248 248 * for you.
249 249 */
250 250 public void removeNodeFromParent(MutableTreeNode node) {
251 251 MutableTreeNode parent = (MutableTreeNode)node.getParent();
252 252
253 253 if(parent == null)
254 254 throw new IllegalArgumentException("node does not have a parent.");
255 255
256 256 int[] childIndex = new int[1];
257 257 Object[] removedArray = new Object[1];
258 258
259 259 childIndex[0] = parent.getIndex(node);
260 260 parent.remove(childIndex[0]);
261 261 removedArray[0] = node;
262 262 nodesWereRemoved(parent, childIndex, removedArray);
263 263 }
264 264
265 265 /**
266 266 * Invoke this method after you've changed how node is to be
267 267 * represented in the tree.
268 268 */
269 269 public void nodeChanged(TreeNode node) {
270 270 if(listenerList != null && node != null) {
271 271 TreeNode parent = node.getParent();
272 272
273 273 if(parent != null) {
274 274 int anIndex = parent.getIndex(node);
275 275 if(anIndex != -1) {
276 276 int[] cIndexs = new int[1];
277 277
278 278 cIndexs[0] = anIndex;
279 279 nodesChanged(parent, cIndexs);
280 280 }
281 281 }
282 282 else if (node == getRoot()) {
283 283 nodesChanged(node, null);
284 284 }
285 285 }
286 286 }
287 287
288 288 /**
289 289 * Invoke this method if you've modified the {@code TreeNode}s upon which
290 290 * this model depends. The model will notify all of its listeners that the
291 291 * model has changed below the given node.
292 292 *
293 293 * @param node the node below which the model has changed
294 294 */
295 295 public void reload(TreeNode node) {
296 296 if(node != null) {
297 297 fireTreeStructureChanged(this, getPathToRoot(node), null, null);
298 298 }
299 299 }
300 300
301 301 /**
302 302 * Invoke this method after you've inserted some TreeNodes into
303 303 * node. childIndices should be the index of the new elements and
304 304 * must be sorted in ascending order.
305 305 */
306 306 public void nodesWereInserted(TreeNode node, int[] childIndices) {
307 307 if(listenerList != null && node != null && childIndices != null
308 308 && childIndices.length > 0) {
309 309 int cCount = childIndices.length;
310 310 Object[] newChildren = new Object[cCount];
311 311
312 312 for(int counter = 0; counter < cCount; counter++)
313 313 newChildren[counter] = node.getChildAt(childIndices[counter]);
314 314 fireTreeNodesInserted(this, getPathToRoot(node), childIndices,
315 315 newChildren);
316 316 }
317 317 }
318 318
319 319 /**
320 320 * Invoke this method after you've removed some TreeNodes from
321 321 * node. childIndices should be the index of the removed elements and
322 322 * must be sorted in ascending order. And removedChildren should be
323 323 * the array of the children objects that were removed.
324 324 */
325 325 public void nodesWereRemoved(TreeNode node, int[] childIndices,
326 326 Object[] removedChildren) {
327 327 if(node != null && childIndices != null) {
328 328 fireTreeNodesRemoved(this, getPathToRoot(node), childIndices,
329 329 removedChildren);
330 330 }
331 331 }
332 332
333 333 /**
334 334 * Invoke this method after you've changed how the children identified by
335 335 * childIndicies are to be represented in the tree.
336 336 */
337 337 public void nodesChanged(TreeNode node, int[] childIndices) {
338 338 if(node != null) {
339 339 if (childIndices != null) {
340 340 int cCount = childIndices.length;
341 341
342 342 if(cCount > 0) {
343 343 Object[] cChildren = new Object[cCount];
344 344
345 345 for(int counter = 0; counter < cCount; counter++)
346 346 cChildren[counter] = node.getChildAt
347 347 (childIndices[counter]);
348 348 fireTreeNodesChanged(this, getPathToRoot(node),
349 349 childIndices, cChildren);
350 350 }
351 351 }
352 352 else if (node == getRoot()) {
353 353 fireTreeNodesChanged(this, getPathToRoot(node), null, null);
354 354 }
355 355 }
356 356 }
357 357
358 358 /**
359 359 * Invoke this method if you've totally changed the children of
360 360 * node and its children's children... This will post a
361 361 * treeStructureChanged event.
362 362 */
363 363 public void nodeStructureChanged(TreeNode node) {
364 364 if(node != null) {
365 365 fireTreeStructureChanged(this, getPathToRoot(node), null, null);
366 366 }
367 367 }
368 368
369 369 /**
370 370 * Builds the parents of node up to and including the root node,
371 371 * where the original node is the last element in the returned array.
372 372 * The length of the returned array gives the node's depth in the
373 373 * tree.
374 374 *
375 375 * @param aNode the TreeNode to get the path for
376 376 */
377 377 public TreeNode[] getPathToRoot(TreeNode aNode) {
378 378 return getPathToRoot(aNode, 0);
379 379 }
380 380
381 381 /**
382 382 * Builds the parents of node up to and including the root node,
383 383 * where the original node is the last element in the returned array.
384 384 * The length of the returned array gives the node's depth in the
385 385 * tree.
386 386 *
387 387 * @param aNode the TreeNode to get the path for
388 388 * @param depth an int giving the number of steps already taken towards
389 389 * the root (on recursive calls), used to size the returned array
390 390 * @return an array of TreeNodes giving the path from the root to the
391 391 * specified node
392 392 */
393 393 protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
394 394 TreeNode[] retNodes;
395 395 // This method recurses, traversing towards the root in order
396 396 // size the array. On the way back, it fills in the nodes,
397 397 // starting from the root and working back to the original node.
398 398
399 399 /* Check for null, in case someone passed in a null node, or
400 400 they passed in an element that isn't rooted at root. */
401 401 if(aNode == null) {
402 402 if(depth == 0)
403 403 return null;
404 404 else
405 405 retNodes = new TreeNode[depth];
406 406 }
407 407 else {
408 408 depth++;
409 409 if(aNode == root)
410 410 retNodes = new TreeNode[depth];
411 411 else
412 412 retNodes = getPathToRoot(aNode.getParent(), depth);
413 413 retNodes[retNodes.length - depth] = aNode;
414 414 }
415 415 return retNodes;
416 416 }
417 417
418 418 //
419 419 // Events
420 420 //
421 421
422 422 /**
423 423 * Adds a listener for the TreeModelEvent posted after the tree changes.
424 424 *
425 425 * @see #removeTreeModelListener
426 426 * @param l the listener to add
427 427 */
428 428 public void addTreeModelListener(TreeModelListener l) {
429 429 listenerList.add(TreeModelListener.class, l);
430 430 }
431 431
432 432 /**
433 433 * Removes a listener previously added with <B>addTreeModelListener()</B>.
434 434 *
435 435 * @see #addTreeModelListener
436 436 * @param l the listener to remove
437 437 */
438 438 public void removeTreeModelListener(TreeModelListener l) {
439 439 listenerList.remove(TreeModelListener.class, l);
440 440 }
441 441
442 442 /**
443 443 * Returns an array of all the tree model listeners
444 444 * registered on this model.
445 445 *
446 446 * @return all of this model's <code>TreeModelListener</code>s
447 447 * or an empty
448 448 * array if no tree model listeners are currently registered
449 449 *
450 450 * @see #addTreeModelListener
451 451 * @see #removeTreeModelListener
452 452 *
453 453 * @since 1.4
454 454 */
455 455 public TreeModelListener[] getTreeModelListeners() {
456 456 return listenerList.getListeners(TreeModelListener.class);
457 457 }
458 458
459 459 /**
460 460 * Notifies all listeners that have registered interest for
461 461 * notification on this event type. The event instance
462 462 * is lazily created using the parameters passed into
463 463 * the fire method.
464 464 *
465 465 * @param source the source of the {@code TreeModelEvent};
466 466 * typically {@code this}
467 467 * @param path the path to the parent of the nodes that changed; use
468 468 * {@code null} to identify the root has changed
469 469 * @param childIndices the indices of the changed elements
470 470 * @param children the changed elements
471 471 */
472 472 protected void fireTreeNodesChanged(Object source, Object[] path,
473 473 int[] childIndices,
474 474 Object[] children) {
475 475 // Guaranteed to return a non-null array
476 476 Object[] listeners = listenerList.getListenerList();
477 477 TreeModelEvent e = null;
478 478 // Process the listeners last to first, notifying
479 479 // those that are interested in this event
480 480 for (int i = listeners.length-2; i>=0; i-=2) {
481 481 if (listeners[i]==TreeModelListener.class) {
482 482 // Lazily create the event:
483 483 if (e == null)
484 484 e = new TreeModelEvent(source, path,
485 485 childIndices, children);
486 486 ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
487 487 }
488 488 }
489 489 }
490 490
491 491 /**
492 492 * Notifies all listeners that have registered interest for
493 493 * notification on this event type. The event instance
494 494 * is lazily created using the parameters passed into
495 495 * the fire method.
496 496 *
497 497 * @param source the source of the {@code TreeModelEvent};
498 498 * typically {@code this}
499 499 * @param path the path to the parent the nodes were added to
500 500 * @param childIndices the indices of the new elements
501 501 * @param children the new elements
502 502 */
503 503 protected void fireTreeNodesInserted(Object source, Object[] path,
504 504 int[] childIndices,
505 505 Object[] children) {
506 506 // Guaranteed to return a non-null array
507 507 Object[] listeners = listenerList.getListenerList();
508 508 TreeModelEvent e = null;
509 509 // Process the listeners last to first, notifying
510 510 // those that are interested in this event
511 511 for (int i = listeners.length-2; i>=0; i-=2) {
512 512 if (listeners[i]==TreeModelListener.class) {
513 513 // Lazily create the event:
514 514 if (e == null)
515 515 e = new TreeModelEvent(source, path,
516 516 childIndices, children);
517 517 ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
518 518 }
519 519 }
520 520 }
521 521
522 522 /**
523 523 * Notifies all listeners that have registered interest for
524 524 * notification on this event type. The event instance
525 525 * is lazily created using the parameters passed into
526 526 * the fire method.
527 527 *
528 528 * @param source the source of the {@code TreeModelEvent};
529 529 * typically {@code this}
530 530 * @param path the path to the parent the nodes were removed from
531 531 * @param childIndices the indices of the removed elements
532 532 * @param children the removed elements
533 533 */
534 534 protected void fireTreeNodesRemoved(Object source, Object[] path,
535 535 int[] childIndices,
536 536 Object[] children) {
537 537 // Guaranteed to return a non-null array
538 538 Object[] listeners = listenerList.getListenerList();
539 539 TreeModelEvent e = null;
540 540 // Process the listeners last to first, notifying
541 541 // those that are interested in this event
542 542 for (int i = listeners.length-2; i>=0; i-=2) {
543 543 if (listeners[i]==TreeModelListener.class) {
544 544 // Lazily create the event:
545 545 if (e == null)
546 546 e = new TreeModelEvent(source, path,
547 547 childIndices, children);
548 548 ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
549 549 }
550 550 }
551 551 }
552 552
553 553 /**
554 554 * Notifies all listeners that have registered interest for
555 555 * notification on this event type. The event instance
556 556 * is lazily created using the parameters passed into
557 557 * the fire method.
558 558 *
559 559 * @param source the source of the {@code TreeModelEvent};
560 560 * typically {@code this}
561 561 * @param path the path to the parent of the structure that has changed;
562 562 * use {@code null} to identify the root has changed
563 563 * @param childIndices the indices of the affected elements
564 564 * @param children the affected elements
565 565 */
566 566 protected void fireTreeStructureChanged(Object source, Object[] path,
567 567 int[] childIndices,
568 568 Object[] children) {
569 569 // Guaranteed to return a non-null array
570 570 Object[] listeners = listenerList.getListenerList();
571 571 TreeModelEvent e = null;
572 572 // Process the listeners last to first, notifying
573 573 // those that are interested in this event
574 574 for (int i = listeners.length-2; i>=0; i-=2) {
575 575 if (listeners[i]==TreeModelListener.class) {
576 576 // Lazily create the event:
577 577 if (e == null)
578 578 e = new TreeModelEvent(source, path,
579 579 childIndices, children);
580 580 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
581 581 }
582 582 }
583 583 }
584 584
585 585 /**
586 586 * Notifies all listeners that have registered interest for
587 587 * notification on this event type. The event instance
588 588 * is lazily created using the parameters passed into
589 589 * the fire method.
590 590 *
591 591 * @param source the source of the {@code TreeModelEvent};
592 592 * typically {@code this}
593 593 * @param path the path to the parent of the structure that has changed;
594 594 * use {@code null} to identify the root has changed
595 595 */
596 596 private void fireTreeStructureChanged(Object source, TreePath path) {
597 597 // Guaranteed to return a non-null array
598 598 Object[] listeners = listenerList.getListenerList();
599 599 TreeModelEvent e = null;
600 600 // Process the listeners last to first, notifying
601 601 // those that are interested in this event
602 602 for (int i = listeners.length-2; i>=0; i-=2) {
603 603 if (listeners[i]==TreeModelListener.class) {
604 604 // Lazily create the event:
605 605 if (e == null)
606 606 e = new TreeModelEvent(source, path);
607 607 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
608 608 }
609 609 }
610 610 }
611 611
612 612 /**
613 613 * Returns an array of all the objects currently registered
614 614 * as <code><em>Foo</em>Listener</code>s
615 615 * upon this model.
616 616 * <code><em>Foo</em>Listener</code>s are registered using the
617 617 * <code>add<em>Foo</em>Listener</code> method.
618 618 *
619 619 * <p>
620 620 *
621 621 * You can specify the <code>listenerType</code> argument
622 622 * with a class literal,
623 623 * such as
624 624 * <code><em>Foo</em>Listener.class</code>.
625 625 * For example, you can query a
626 626 * <code>DefaultTreeModel</code> <code>m</code>
627 627 * for its tree model listeners with the following code:
628 628 *
629 629 * <pre>TreeModelListener[] tmls = (TreeModelListener[])(m.getListeners(TreeModelListener.class));</pre>
630 630 *
631 631 * If no such listeners exist, this method returns an empty array.
632 632 *
633 633 * @param listenerType the type of listeners requested; this parameter
634 634 * should specify an interface that descends from
635 635 * <code>java.util.EventListener</code>
636 636 * @return an array of all objects registered as
637 637 * <code><em>Foo</em>Listener</code>s on this component,
638 638 * or an empty array if no such
639 639 * listeners have been added
640 640 * @exception ClassCastException if <code>listenerType</code>
641 641 * doesn't specify a class or interface that implements
642 642 * <code>java.util.EventListener</code>
643 643 *
644 644 * @see #getTreeModelListeners
645 645 *
646 646 * @since 1.3
647 647 */
648 648 public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
649 649 return listenerList.getListeners(listenerType);
650 650 }
651 651
652 652 // Serialization support.
653 653 private void writeObject(ObjectOutputStream s) throws IOException {
654 654 Vector<Object> values = new Vector<Object>();
655 655
656 656 s.defaultWriteObject();
657 657 // Save the root, if its Serializable.
658 658 if(root != null && root instanceof Serializable) {
659 659 values.addElement("root");
660 660 values.addElement(root);
661 661 }
662 662 s.writeObject(values);
663 663 }
664 664
665 665 private void readObject(ObjectInputStream s)
666 666 throws IOException, ClassNotFoundException {
667 667 s.defaultReadObject();
668 668
669 669 Vector values = (Vector)s.readObject();
670 670 int indexCounter = 0;
671 671 int maxCounter = values.size();
672 672
673 673 if(indexCounter < maxCounter && values.elementAt(indexCounter).
674 674 equals("root")) {
675 675 root = (TreeNode)values.elementAt(++indexCounter);
676 676 indexCounter++;
677 677 }
678 678 }
679 679
680 680
681 681 } // End of class DefaultTreeModel
↓ open down ↓ |
635 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX