Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / javax / swing / tree / DefaultTreeSelectionModel.java
blob0676f7ec8f4681cc4ce80fe7d4782eea3da89bb7
1 /* DefaultTreeSelectionModel.java
2 Copyright (C) 2002, 2004, 2005, 2006 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. */
39 package javax.swing.tree;
41 import java.beans.PropertyChangeListener;
42 import java.io.IOException;
43 import java.io.ObjectInputStream;
44 import java.io.ObjectOutputStream;
45 import java.io.Serializable;
46 import java.util.Arrays;
47 import java.util.EventListener;
48 import java.util.HashSet;
49 import java.util.Iterator;
50 import java.util.Vector;
52 import javax.swing.DefaultListSelectionModel;
53 import javax.swing.event.EventListenerList;
54 import javax.swing.event.SwingPropertyChangeSupport;
55 import javax.swing.event.TreeSelectionEvent;
56 import javax.swing.event.TreeSelectionListener;
58 /**
59 * The implementation of the default tree selection model. The installed
60 * listeners are notified about the path and not the row changes. If you
61 * specifically need to track the row changes, register the listener for the
62 * expansion events.
64 * @author Andrew Selkirk
65 * @author Audrius Meskauskas
67 public class DefaultTreeSelectionModel
68 implements Cloneable, Serializable, TreeSelectionModel
71 /**
72 * Use serialVersionUID for interoperability.
74 static final long serialVersionUID = 3288129636638950196L;
76 /**
77 * The name of the selection mode property.
79 public static final String SELECTION_MODE_PROPERTY = "selectionMode";
81 /**
82 * Our Swing property change support.
84 protected SwingPropertyChangeSupport changeSupport;
86 /**
87 * The current selection.
89 protected TreePath[] selection;
91 /**
92 * Our TreeSelectionListeners.
94 protected EventListenerList listenerList;
96 /**
97 * The current RowMapper.
99 protected transient RowMapper rowMapper;
102 * The current listSelectionModel.
104 protected DefaultListSelectionModel listSelectionModel;
107 * The current selection mode.
109 protected int selectionMode;
112 * The path that has been added last.
114 protected TreePath leadPath;
117 * The index of the last added path.
119 protected int leadIndex;
122 * The row of the last added path according to the RowMapper.
124 protected int leadRow = -1;
127 * Constructs a new DefaultTreeSelectionModel.
129 public DefaultTreeSelectionModel()
131 setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);
132 listenerList = new EventListenerList();
136 * Creates a clone of this DefaultTreeSelectionModel with the same selection.
137 * The cloned instance will have the same registered listeners, the listeners
138 * themselves will not be cloned. The selection will be cloned.
140 * @exception CloneNotSupportedException should not be thrown here
141 * @return a copy of this DefaultTreeSelectionModel
143 public Object clone() throws CloneNotSupportedException
145 DefaultTreeSelectionModel cloned =
146 (DefaultTreeSelectionModel) super.clone();
148 // Clone the selection and the list selection model.
149 cloned.selection = (TreePath[]) selection.clone();
150 if (listSelectionModel!=null)
151 cloned.listSelectionModel =
152 (DefaultListSelectionModel) listSelectionModel.clone();
153 return cloned;
157 * Returns a string that shows this object's properties.
158 * The returned string lists the selected tree rows, if any.
160 * @return a string that shows this object's properties
162 public String toString()
164 if (isSelectionEmpty())
165 return "[selection empty]";
166 else
168 StringBuffer b = new StringBuffer("selected rows: [");
169 for (int i = 0; i < selection.length; i++)
171 b.append(getRow(selection[i]));
172 b.append(' ');
174 b.append(", lead "+getLeadSelectionRow());
175 return b.toString();
180 * writeObject
182 * @param value0 TODO
183 * @exception IOException TODO
185 private void writeObject(ObjectOutputStream value0) throws IOException
187 // TODO
191 * readObject
193 * @param value0 TODO
194 * @exception IOException TODO
195 * @exception ClassNotFoundException TODO
197 private void readObject(ObjectInputStream value0) throws IOException,
198 ClassNotFoundException
200 // TODO
204 * Sets the RowMapper that should be used to map between paths and their rows.
206 * @param mapper the RowMapper to set
207 * @see RowMapper
209 public void setRowMapper(RowMapper mapper)
211 rowMapper = mapper;
215 * Returns the RowMapper that is currently used to map between paths and their
216 * rows.
218 * @return the current RowMapper
219 * @see RowMapper
221 public RowMapper getRowMapper()
223 return rowMapper;
227 * Sets the current selection mode. Possible values are
228 * {@link #SINGLE_TREE_SELECTION}, {@link #CONTIGUOUS_TREE_SELECTION} and
229 * {@link #DISCONTIGUOUS_TREE_SELECTION}.
231 * @param mode the selection mode to be set
232 * @see #getSelectionMode
233 * @see #SINGLE_TREE_SELECTION
234 * @see #CONTIGUOUS_TREE_SELECTION
235 * @see #DISCONTIGUOUS_TREE_SELECTION
237 public void setSelectionMode(int mode)
239 selectionMode = mode;
240 insureRowContinuity();
244 * Returns the current selection mode.
246 * @return the current selection mode
247 * @see #setSelectionMode
248 * @see #SINGLE_TREE_SELECTION
249 * @see #CONTIGUOUS_TREE_SELECTION
250 * @see #DISCONTIGUOUS_TREE_SELECTION
252 public int getSelectionMode()
254 return selectionMode;
258 * Sets this path as the only selection. If this changes the selection the
259 * registered TreeSelectionListeners are notified.
261 * @param path the path to set as selection
263 public void setSelectionPath(TreePath path)
265 // The most frequently only one cell in the tree is selected.
266 TreePath[] ose = selection;
267 selection = new TreePath[] { path };
268 TreePath oldLead = leadPath;
269 leadIndex = 0;
270 leadRow = getRow(path);
271 leadPath = path;
273 TreeSelectionEvent event;
275 if (ose != null && ose.length > 0)
277 // The first item in the path list is the selected path.
278 // The remaining items are unselected pathes.
279 TreePath[] changed = new TreePath[ose.length + 1];
280 boolean[] news = new boolean[changed.length];
281 news[0] = true;
282 changed[0] = path;
283 System.arraycopy(ose, 0, changed, 1, ose.length);
284 event = new TreeSelectionEvent(this, changed, news, oldLead, path);
286 else
288 event = new TreeSelectionEvent(this, path, true, oldLead, path);
290 fireValueChanged(event);
294 * Get the number of the tree row for the given path.
296 * @param path the tree path
297 * @return the tree row for this path or -1 if the path is not visible.
299 int getRow(TreePath path)
301 RowMapper mapper = getRowMapper();
303 if (mapper instanceof AbstractLayoutCache)
305 // The absolute majority of cases, unless the TreeUI is very
306 // seriously rewritten
307 AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
308 return ama.getRowForPath(path);
310 else
312 // Generic non optimized implementation.
313 int[] rows = mapper.getRowsForPaths(new TreePath[] { path });
314 if (rows.length == 0)
315 return - 1;
316 else
317 return rows[0];
322 * Sets the paths as selection. This method checks for duplicates and removes
323 * them. If this changes the selection the registered TreeSelectionListeners
324 * are notified.
326 * @param paths the paths to set as selection
328 public void setSelectionPaths(TreePath[] paths)
330 // Must be called, as defined in JDK API 1.4.
331 insureUniqueness();
332 clearSelection();
333 addSelectionPaths(paths);
337 * Adds a path to the list of selected paths. This method checks if the path
338 * is already selected and doesn't add the same path twice. If this changes
339 * the selection the registered TreeSelectionListeners are notified.
341 * The lead path is changed to the added path. This also happen if the
342 * passed path was already selected before.
344 * @param path the path to add to the selection
346 public void addSelectionPath(TreePath path)
348 if (! isPathSelected(path))
350 if (selectionMode == SINGLE_TREE_SELECTION || isSelectionEmpty()
351 || ! canPathBeAdded(path))
352 setSelectionPath(path);
353 else
355 TreePath[] temp = new TreePath[selection.length + 1];
356 System.arraycopy(selection, 0, temp, 0, selection.length);
357 temp[temp.length - 1] = path;
358 selection = new TreePath[temp.length];
359 System.arraycopy(temp, 0, selection, 0, temp.length);
363 if (path!=leadPath)
365 TreePath oldLead = leadPath;
366 leadPath = path;
367 leadRow = getRow(path);
368 leadIndex = selection.length - 1;
369 fireValueChanged(new TreeSelectionEvent(this, path, true, oldLead,
370 leadPath));
375 * Adds the paths to the list of selected paths. This method checks if the
376 * paths are already selected and doesn't add the same path twice. If this
377 * changes the selection the registered TreeSelectionListeners are notified.
379 * @param paths the paths to add to the selection
381 public void addSelectionPaths(TreePath[] paths)
383 // Must be called, as defined in JDK API 1.4.
384 insureUniqueness();
386 if (paths != null)
388 TreePath v0 = null;
389 for (int i = 0; i < paths.length; i++)
391 v0 = paths[i];
392 if (! isPathSelected(v0))
394 if (isSelectionEmpty())
395 setSelectionPath(v0);
396 else
398 TreePath[] temp = new TreePath[selection.length + 1];
399 System.arraycopy(selection, 0, temp, 0, selection.length);
400 temp[temp.length - 1] = v0;
401 selection = new TreePath[temp.length];
402 System.arraycopy(temp, 0, selection, 0, temp.length);
404 TreePath oldLead = leadPath;
405 leadPath = paths[paths.length - 1];
406 leadRow = getRow(leadPath);
407 leadIndex = selection.length - 1;
409 fireValueChanged(new TreeSelectionEvent(this, v0, true,
410 oldLead, leadPath));
413 insureRowContinuity();
418 * Removes the path from the selection. If this changes the selection the
419 * registered TreeSelectionListeners are notified.
421 * @param path the path to remove
423 public void removeSelectionPath(TreePath path)
425 if (isSelectionEmpty())
426 return;
428 int index = - 1;
429 if (isPathSelected(path))
431 for (int i = 0; i < selection.length; i++)
433 if (selection[i].equals(path))
435 index = i;
436 break;
439 TreePath[] temp = new TreePath[selection.length - 1];
440 System.arraycopy(selection, 0, temp, 0, index);
441 System.arraycopy(selection, index + 1, temp, index, selection.length
442 - index - 1);
443 selection = new TreePath[temp.length];
444 System.arraycopy(temp, 0, selection, 0, temp.length);
446 // If the removed path was the lead path, set the lead path to null.
447 TreePath oldLead = leadPath;
448 if (path!=null && leadPath!=null && path.equals(leadPath))
449 leadPath = null;
451 fireValueChanged(new TreeSelectionEvent(this, path, false, oldLead,
452 leadPath));
453 insureRowContinuity();
458 * Removes the paths from the selection. If this changes the selection the
459 * registered TreeSelectionListeners are notified.
461 * @param paths the paths to remove
463 public void removeSelectionPaths(TreePath[] paths)
465 if (isSelectionEmpty())
466 return;
467 if (paths != null)
469 int index = - 1;
470 TreePath v0 = null;
471 TreePath oldLead = leadPath;
472 for (int i = 0; i < paths.length; i++)
474 v0 = paths[i];
475 if (isPathSelected(v0))
477 for (int x = 0; x < selection.length; x++)
479 if (selection[i].equals(v0))
481 index = x;
482 break;
484 if (leadPath != null && leadPath.equals(v0))
485 leadPath = null;
487 TreePath[] temp = new TreePath[selection.length - 1];
488 System.arraycopy(selection, 0, temp, 0, index);
489 System.arraycopy(selection, index + 1, temp, index,
490 selection.length - index - 1);
491 selection = new TreePath[temp.length];
492 System.arraycopy(temp, 0, selection, 0, temp.length);
494 fireValueChanged(new TreeSelectionEvent(this, v0, false,
495 oldLead, leadPath));
498 insureRowContinuity();
503 * Returns the first path in the selection. This is especially useful when the
504 * selectionMode is {@link #SINGLE_TREE_SELECTION}.
506 * @return the first path in the selection
508 public TreePath getSelectionPath()
510 if ((selection == null) || (selection.length == 0))
511 return null;
512 else
513 return selection[0];
517 * Returns the complete selection.
519 * @return the complete selection
521 public TreePath[] getSelectionPaths()
523 return selection;
527 * Returns the number of paths in the selection.
529 * @return the number of paths in the selection
531 public int getSelectionCount()
533 if (selection == null)
534 return 0;
535 else
536 return selection.length;
540 * Checks if a given path is in the selection.
542 * @param path the path to check
543 * @return <code>true</code> if the path is in the selection,
544 * <code>false</code> otherwise
546 public boolean isPathSelected(TreePath path)
548 if (selection == null)
549 return false;
551 for (int i = 0; i < selection.length; i++)
553 if (selection[i].equals(path))
554 return true;
556 return false;
560 * Checks if the selection is empty.
562 * @return <code>true</code> if the selection is empty, <code>false</code>
563 * otherwise
565 public boolean isSelectionEmpty()
567 return ((selection == null) || (selection.length == 0));
571 * Removes all paths from the selection. Fire the unselection event.
573 public void clearSelection()
575 if (! isSelectionEmpty())
577 TreeSelectionEvent event = new TreeSelectionEvent(
578 this, selection, new boolean[selection.length], leadPath, null);
579 leadPath = null;
580 selection = null;
581 fireValueChanged(event);
583 else
585 leadPath = null;
586 selection = null;
591 * Adds a <code>TreeSelectionListener</code> object to this model.
593 * @param listener the listener to add
595 public void addTreeSelectionListener(TreeSelectionListener listener)
597 listenerList.add(TreeSelectionListener.class, listener);
601 * Removes a <code>TreeSelectionListener</code> object from this model.
603 * @param listener the listener to remove
605 public void removeTreeSelectionListener(TreeSelectionListener listener)
607 listenerList.remove(TreeSelectionListener.class, listener);
611 * Returns all <code>TreeSelectionListener</code> added to this model.
613 * @return an array of listeners
614 * @since 1.4
616 public TreeSelectionListener[] getTreeSelectionListeners()
618 return (TreeSelectionListener[]) getListeners(TreeSelectionListener.class);
622 * fireValueChanged
624 * @param event the event to fire.
626 protected void fireValueChanged(TreeSelectionEvent event)
628 TreeSelectionListener[] listeners = getTreeSelectionListeners();
630 for (int i = 0; i < listeners.length; ++i)
631 listeners[i].valueChanged(event);
635 * Returns all added listeners of a special type.
637 * @param listenerType the listener type
638 * @return an array of listeners
639 * @since 1.3
641 public EventListener[] getListeners(Class listenerType)
643 return listenerList.getListeners(listenerType);
647 * Returns the currently selected rows.
649 * @return the currently selected rows
651 public int[] getSelectionRows()
653 if (rowMapper == null)
654 return null;
655 else
656 return rowMapper.getRowsForPaths(selection);
660 * Returns the smallest row index from the selection.
662 * @return the smallest row index from the selection
664 public int getMinSelectionRow()
666 if ((rowMapper == null) || (selection == null) || (selection.length == 0))
667 return - 1;
668 else
670 int[] rows = rowMapper.getRowsForPaths(selection);
671 int minRow = Integer.MAX_VALUE;
672 for (int index = 0; index < rows.length; index++)
673 minRow = Math.min(minRow, rows[index]);
674 return minRow;
679 * Returns the largest row index from the selection.
681 * @return the largest row index from the selection
683 public int getMaxSelectionRow()
685 if ((rowMapper == null) || (selection == null) || (selection.length == 0))
686 return - 1;
687 else
689 int[] rows = rowMapper.getRowsForPaths(selection);
690 int maxRow = - 1;
691 for (int index = 0; index < rows.length; index++)
692 maxRow = Math.max(maxRow, rows[index]);
693 return maxRow;
698 * Checks if a particular row is selected.
700 * @param row the index of the row to check
701 * @return <code>true</code> if the row is in this selection,
702 * <code>false</code> otherwise
703 * @throws NullPointerException if the row mapper is not set (can only happen
704 * if the user has plugged in the custom incorrect TreeUI
705 * implementation.
707 public boolean isRowSelected(int row)
709 // Return false if nothing is selected.
710 if (isSelectionEmpty())
711 return false;
713 RowMapper mapper = getRowMapper();
715 if (mapper instanceof AbstractLayoutCache)
717 // The absolute majority of cases, unless the TreeUI is very
718 // seriously rewritten
719 AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
720 TreePath path = ama.getPathForRow(row);
721 return isPathSelected(path);
723 else
725 // Generic non optimized implementation.
726 int[] rows = mapper.getRowsForPaths(selection);
727 for (int i = 0; i < rows.length; i++)
728 if (rows[i] == row)
729 return true;
730 return false;
735 * Updates the mappings from TreePaths to row indices.
737 public void resetRowSelection()
739 // Nothing to do here.
743 * getLeadSelectionRow
745 * @return int
747 public int getLeadSelectionRow()
749 return leadRow;
753 * getLeadSelectionPath
755 * @return TreePath
757 public TreePath getLeadSelectionPath()
759 return leadPath;
763 * Adds a <code>PropertyChangeListener</code> object to this model.
765 * @param listener the listener to add.
767 public void addPropertyChangeListener(PropertyChangeListener listener)
769 changeSupport.addPropertyChangeListener(listener);
773 * Removes a <code>PropertyChangeListener</code> object from this model.
775 * @param listener the listener to remove.
777 public void removePropertyChangeListener(PropertyChangeListener listener)
779 changeSupport.removePropertyChangeListener(listener);
783 * Returns all added <code>PropertyChangeListener</code> objects.
785 * @return an array of listeners.
786 * @since 1.4
788 public PropertyChangeListener[] getPropertyChangeListeners()
790 return changeSupport.getPropertyChangeListeners();
794 * Makes sure the currently selected paths are valid according to the current
795 * selectionMode. If the selectionMode is set to
796 * {@link #CONTIGUOUS_TREE_SELECTION} and the selection isn't contiguous then
797 * the selection is reset to the first set of contguous paths. If the
798 * selectionMode is set to {@link #SINGLE_TREE_SELECTION} and the selection
799 * has more than one path, the selection is reset to the contain only the
800 * first path.
802 protected void insureRowContinuity()
804 if (selection == null || selection.length < 2)
805 return;
806 else if (selectionMode == CONTIGUOUS_TREE_SELECTION)
808 if (rowMapper == null)
809 // This is the best we can do without the row mapper:
810 selectOne();
811 else
813 int[] rows = rowMapper.getRowsForPaths(selection);
814 Arrays.sort(rows);
815 int i;
816 for (i = 1; i < rows.length; i++)
818 if (rows[i - 1] != rows[i] - 1)
819 // Break if no longer continuous.
820 break;
823 if (i < rows.length)
825 TreePath[] ns = new TreePath[i];
826 for (int j = 0; j < ns.length; j++)
827 ns[i] = getPath(j);
828 setSelectionPaths(ns);
832 else if (selectionMode == SINGLE_TREE_SELECTION)
833 selectOne();
837 * Keep only one (normally last or leading) path in the selection.
839 private void selectOne()
841 if (leadIndex > 0 && leadIndex < selection.length)
842 setSelectionPath(selection[leadIndex]);
843 else
844 setSelectionPath(selection[selection.length -1]);
848 * Get path for the given row that must be in the current selection.
850 private TreePath getPath(int row)
852 if (rowMapper instanceof AbstractLayoutCache)
853 return ((AbstractLayoutCache) rowMapper).getPathForRow(row);
854 else
856 int[] rows = rowMapper.getRowsForPaths(selection);
857 for (int i = 0; i < rows.length; i++)
858 if (rows[i] == row)
859 return selection[i];
861 throw new InternalError(row + " not in selection");
865 * Returns <code>true</code> if the paths are contiguous (take subsequent
866 * rows in the diplayed tree view. The method returns <code>true</code> if
867 * we have no RowMapper assigned.
869 * @param paths the paths to check for continuity
870 * @return <code>true</code> if the paths are contiguous or we have no
871 * RowMapper assigned
873 protected boolean arePathsContiguous(TreePath[] paths)
875 if (rowMapper == null || paths.length < 2)
876 return true;
878 int[] rows = rowMapper.getRowsForPaths(paths);
880 // The patches may not be sorted.
881 Arrays.sort(rows);
883 for (int i = 1; i < rows.length; i++)
885 if (rows[i-1] != rows[i] - 1)
886 return false;
888 return true;
892 * Checks if the paths can be added. This returns <code>true</code> if:
893 * <ul>
894 * <li><code>paths</code> is <code>null</code> or empty</li>
895 * <li>we have no RowMapper assigned</li>
896 * <li>nothing is currently selected</li>
897 * <li>selectionMode is {@link #DISCONTIGUOUS_TREE_SELECTION}</li>
898 * <li>adding the paths to the selection still results in a contiguous set of
899 * paths</li>
901 * @param paths the paths to check
902 * @return <code>true</code> if the paths can be added with respect to the
903 * selectionMode
905 protected boolean canPathsBeAdded(TreePath[] paths)
907 if (rowMapper == null || isSelectionEmpty()
908 || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
909 return true;
911 TreePath [] all = new TreePath[paths.length + selection.length];
912 System.arraycopy(paths, 0, all, 0, paths.length);
913 System.arraycopy(selection, 0, all, paths.length, selection.length);
915 return arePathsContiguous(all);
919 * Checks if the single path can be added to selection.
921 private boolean canPathBeAdded(TreePath path)
923 if (rowMapper == null || isSelectionEmpty()
924 || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
925 return true;
927 TreePath[] all = new TreePath[selection.length + 1];
928 System.arraycopy(selection, 0, all, 0, selection.length);
929 all[all.length - 1] = path;
931 return arePathsContiguous(all);
935 * Checks if the paths can be removed without breaking the continuity of the
936 * selection according to selectionMode.
938 * @param paths the paths to check
939 * @return <code>true</code> if the paths can be removed with respect to the
940 * selectionMode
942 protected boolean canPathsBeRemoved(TreePath[] paths)
944 if (rowMapper == null || isSelectionEmpty()
945 || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
946 return true;
948 HashSet set = new HashSet();
949 for (int i = 0; i < selection.length; i++)
950 set.add(selection[i]);
952 for (int i = 0; i < paths.length; i++)
953 set.remove(paths[i]);
955 TreePath[] remaining = new TreePath[set.size()];
956 Iterator iter = set.iterator();
958 for (int i = 0; i < remaining.length; i++)
959 remaining[i] = (TreePath) iter.next();
961 return arePathsContiguous(remaining);
965 * Notify the installed listeners that the given patches have changed. This
966 * method will call listeners if invoked, but it is not called from the
967 * implementation of this class.
969 * @param vPathes the vector of the changed patches
970 * @param oldLeadSelection the old selection index
972 protected void notifyPathChange(Vector vPathes, TreePath oldLeadSelection)
974 TreePath[] pathes = new TreePath[vPathes.size()];
975 for (int i = 0; i < pathes.length; i++)
976 pathes[i] = (TreePath) vPathes.get(i);
978 boolean[] news = new boolean[pathes.length];
979 for (int i = 0; i < news.length; i++)
980 news[i] = isPathSelected(pathes[i]);
982 TreeSelectionEvent event = new TreeSelectionEvent(this, pathes, news,
983 oldLeadSelection,
984 leadPath);
985 fireValueChanged(event);
989 * Updates the lead selection row number after changing the lead selection
990 * path.
992 protected void updateLeadIndex()
994 if (isSelectionEmpty())
996 leadRow = leadIndex = - 1;
998 else
1000 leadRow = getRow(leadPath);
1001 for (int i = 0; i < selection.length; i++)
1003 if (selection[i].equals(leadPath))
1005 leadIndex = i;
1006 break;
1009 leadIndex = leadRow;
1014 * This method exists due historical reasons and returns without action
1015 * (unless overridden). For compatibility with the applications that override
1016 * it, it is still called from the {@link #setSelectionPaths(TreePath[])} and
1017 * {@link #addSelectionPaths(TreePath[])}.
1019 protected void insureUniqueness()
1021 // Following the API 1.4, the method should return without action.