OSDN Git Service

Imported Classpath 0.18.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / tree / DefaultTreeSelectionModel.java
1 /* DefaultTreeSelectionModel.java 
2    Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
3    
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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.
20
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.
25
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. */
37
38 package javax.swing.tree;
39
40 import java.beans.PropertyChangeListener;
41 import java.io.IOException;
42 import java.io.ObjectInputStream;
43 import java.io.ObjectOutputStream;
44 import java.io.Serializable;
45 import java.util.EventListener;
46 import java.util.Vector;
47
48 import javax.swing.DefaultListSelectionModel;
49 import javax.swing.event.EventListenerList;
50 import javax.swing.event.SwingPropertyChangeSupport;
51 import javax.swing.event.TreeSelectionEvent;
52 import javax.swing.event.TreeSelectionListener;
53
54 /**
55  * DefaultTreeSelectionModel
56  * 
57  * @author Andrew Selkirk
58  */
59 public class DefaultTreeSelectionModel
60                 implements Cloneable, Serializable, TreeSelectionModel
61 {
62         static final long serialVersionUID = 3288129636638950196L;
63
64         /**
65          * SELECTION_MODE_PROPERTY
66          */
67         public static final String SELECTION_MODE_PROPERTY = "selectionMode";
68
69         /**
70          * Our Swing property change support.
71          */
72         protected SwingPropertyChangeSupport changeSupport;
73
74         /**
75          * The current selection.
76          */
77         protected TreePath[] selection;
78
79         /**
80          * Our TreeSelectionListeners.
81          */
82         protected EventListenerList listenerList;
83
84         /**
85          * The current RowMapper.
86          */
87         protected transient RowMapper rowMapper;
88
89         /**
90          * The current listSelectionModel.
91          */
92         protected DefaultListSelectionModel listSelectionModel;
93
94         /**
95          * The current selection mode.
96          */
97         protected int selectionMode;
98
99         /**
100          * The path that has been added last.
101          */
102         protected TreePath leadPath;
103
104         /**
105          * The index of the last added path.
106          */
107         protected int leadIndex;
108
109         /**
110          * The row of the last added path according to the RowMapper.
111          */
112         protected int leadRow;
113
114         /**
115          * Constructs a new DefaultTreeSelectionModel.
116          */
117         public DefaultTreeSelectionModel()
118         {
119                 setSelectionMode(SINGLE_TREE_SELECTION);
120                 listenerList = new EventListenerList();
121         }
122
123         /**
124          * Creates a clone of this DefaultTreeSelectionModel with the same
125          * selection.
126          * 
127          * @exception CloneNotSupportedException should not be thrown here
128          * 
129          * @return a clone of this DefaultTreeSelectionModel
130          */
131         public Object clone() throws CloneNotSupportedException
132         {
133                 return null; // TODO
134         }
135
136         /**
137          * Returns a string that shows this object's properties.
138          * 
139          * @return a string that shows this object's properties
140          */
141         public String toString()
142         {
143                 return null; // TODO
144         }
145
146         /**
147          * writeObject
148          * 
149          * @param value0 TODO
150          * @exception IOException TODO
151          */
152         private void writeObject(ObjectOutputStream value0) throws IOException
153         {
154                 // TODO
155         }
156
157         /**
158          * readObject
159          * 
160          * @param value0 TODO
161          * @exception IOException TODO
162          * @exception ClassNotFoundException TODO
163          */
164         private void readObject(ObjectInputStream value0) throws IOException,
165                         ClassNotFoundException
166         {
167                 // TODO
168         }
169
170         /**
171          * Sets the RowMapper that should be used to map between paths and their
172          * rows.
173          * 
174          * @param rowMapper the RowMapper to set
175          * 
176          * @see RowMapper
177          */
178         public void setRowMapper(RowMapper rowMapper)
179         {
180                 // TODO
181         }
182
183         /**
184          * Returns the RowMapper that is currently used to map between paths and
185          * their rows.
186          * 
187          * @return the current RowMapper
188          * 
189          * @see RowMapper
190          */
191         public RowMapper getRowMapper()
192         {
193                 return rowMapper;
194         }
195
196         /**
197          * Sets the current selection mode. Possible values are
198          * {@link #SINGLE_TREE_SELECTION}, {@link #CONTIGUOUS_TREE_SELECTION} and
199          * {@link #DISCONTIGUOUS_TREE_SELECTION}.
200          * 
201          * @param mode the selection mode to be set
202          * 
203          * @see #getSelectionMode
204          * @see #SINGLE_TREE_SELECTION
205          * @see #CONTIGUOUS_TREE_SELECTION
206          * @see #DISCONTIGUOUS_TREE_SELECTION
207          */
208         public void setSelectionMode(int mode)
209         {
210                 selectionMode = mode;
211         }
212
213         /**
214          * Returns the current selection mode.
215          * 
216          * @return the current selection mode
217          * 
218          * @see #setSelectionMode
219          * @see #SINGLE_TREE_SELECTION
220          * @see #CONTIGUOUS_TREE_SELECTION
221          * @see #DISCONTIGUOUS_TREE_SELECTION
222          */
223         public int getSelectionMode()
224         {
225                 return selectionMode;
226         }
227
228         /**
229          * Sets this path as the only selection.
230          * 
231          * If this changes the selection the registered TreeSelectionListeners are
232          * notified.
233          * 
234          * @param path the path to set as selection
235          */
236         public void setSelectionPath(TreePath path)
237         {
238                 selection = new TreePath[] {
239                         path };
240         }
241
242         /**
243          * Sets the paths as selection. This method checks for duplicates and
244          * removes them.
245          * 
246          * If this changes the selection the registered TreeSelectionListeners are
247          * notified.
248          * 
249          * @param paths the paths to set as selection
250          */
251         public void setSelectionPaths(TreePath[] paths)
252         {
253                 // TODO
254         }
255
256         /**
257          * Adds a path to the list of selected paths. This method checks if the path
258          * is already selected and doesn't add the same path twice.
259          * 
260          * If this changes the selection the registered TreeSelectionListeners are
261          * notified.
262          * 
263          * @param path the path to add to the selection
264          */
265         public void addSelectionPath(TreePath path)
266         {
267                 if (!isPathSelected(path))
268                 {
269                         if (isSelectionEmpty())
270                                 setSelectionPath(path);
271                         else
272                         {
273                                 TreePath[] temp = new TreePath[selection.length + 1];
274                                 System.arraycopy(selection, 0, temp, 0, selection.length);
275                                 temp[temp.length - 1] = path;
276                                 selection = new TreePath[temp.length];
277                                 System.arraycopy(temp, 0, selection, 0, temp.length);
278                         }
279                         leadPath = path;
280                         fireValueChanged(new TreeSelectionEvent(this, path, true,
281                                         leadPath, path));
282                 }
283         }
284
285         /**
286          * Adds the paths to the list of selected paths. This method checks if the
287          * paths are already selected and doesn't add the same path twice.
288          * 
289          * If this changes the selection the registered TreeSelectionListeners are
290          * notified.
291          * 
292          * @param paths the paths to add to the selection
293          */
294         public void addSelectionPaths(TreePath[] paths)
295         {
296                 if (paths != null)
297                 {
298                         TreePath v0 = null;
299                         for (int i = 0; i < paths.length; i++)
300                         {
301                                 v0 = paths[i];
302                                 if (!isPathSelected(v0))
303                                 {
304                                         if (isSelectionEmpty())
305                                                 setSelectionPath(v0);
306                                         else
307                                         {
308                                                 TreePath[] temp = new TreePath[selection.length + 1];
309                                                 System.arraycopy(selection, 0, temp, 0,
310                                                                 selection.length);
311                                                 temp[temp.length - 1] = v0;
312                                                 selection = new TreePath[temp.length];
313                                                 System.arraycopy(temp, 0, selection, 0, temp.length);
314                                         }
315                                         leadPath = paths[paths.length - 1];
316                                         fireValueChanged(new TreeSelectionEvent(this, v0, true,
317                                                         leadPath, paths[0]));
318                                 }
319                         }
320                 }
321         }
322
323         /**
324          * Removes the path from the selection.
325          * 
326          * If this changes the selection the registered TreeSelectionListeners are
327          * notified.
328          * 
329          * @param path the path to remove
330          */
331         public void removeSelectionPath(TreePath path)
332         {
333                 int index = -1;
334                 if (isPathSelected(path))
335                 {
336                         for (int i = 0; i < selection.length; i++)
337                         {
338                                 if (selection[i].equals(path))
339                                 {
340                                         index = i;
341                                         break;
342                                 }
343                         }
344                         TreePath[] temp = new TreePath[selection.length - 1];
345                         System.arraycopy(selection, 0, temp, 0, index);
346                         System.arraycopy(selection, index + 1, temp, index,
347                                         selection.length - index - 1);
348                         selection = new TreePath[temp.length];
349                         System.arraycopy(temp, 0, selection, 0, temp.length);
350
351                         fireValueChanged(new TreeSelectionEvent(this, path, false,
352                                         leadPath, path));
353                 }
354         }
355
356         /**
357          * Removes the paths from the selection.
358          * 
359          * If this changes the selection the registered TreeSelectionListeners are
360          * notified.
361          * 
362          * @param paths the paths to remove
363          */
364         public void removeSelectionPaths(TreePath[] paths)
365         {
366                 if (paths != null)
367                 {
368                         int index = -1;
369                         TreePath v0 = null;
370                         for (int i = 0; i < paths.length; i++)
371                         {
372                                 v0 = paths[i];
373                                 if (isPathSelected(v0))
374                                 {
375                                         for (int x = 0; x < selection.length; x++)
376                                         {
377                                                 if (selection[i].equals(v0))
378                                                 {
379                                                         index = x;
380                                                         break;
381                                                 }
382                                         }
383                                         TreePath[] temp = new TreePath[selection.length - 1];
384                                         System.arraycopy(selection, 0, temp, 0, index);
385                                         System.arraycopy(selection, index + 1, temp, index,
386                                                         selection.length - index - 1);
387                                         selection = new TreePath[temp.length];
388                                         System.arraycopy(temp, 0, selection, 0, temp.length);
389
390                                         fireValueChanged(new TreeSelectionEvent(this, v0, false,
391                                                         leadPath, paths[0]));
392                                 }
393                         }
394                 }
395         }
396
397         /**
398          * Returns the first path in the selection. This is especially useful when
399          * the selectionMode is {@link #SINGLE_TREE_SELECTION}.
400          * 
401          * @return the first path in the selection
402          */
403         public TreePath getSelectionPath()
404         {
405                 if ((selection == null) || (selection.length == 0))
406                         return null;
407                 else
408                         return selection[0];
409         }
410
411         /**
412          * Returns the complete selection.
413          * 
414          * @return the complete selection
415          */
416         public TreePath[] getSelectionPaths()
417         {
418                 return selection;
419         }
420
421         /**
422          * Returns the number of paths in the selection.
423          * 
424          * @return the number of paths in the selection
425          */
426         public int getSelectionCount()
427         {
428                 if (selection == null)
429                         return 0;
430                 else
431                         return selection.length;
432         }
433
434         /**
435          * Checks if a given path is in the selection.
436          * 
437          * @param path the path to check
438          * 
439          * @return <code>true</code> if the path is in the selection,
440          *         <code>false</code> otherwise
441          */
442         public boolean isPathSelected(TreePath path)
443         {
444                 if (selection == null)
445                         return false;
446
447                 for (int i = 0; i < selection.length; i++)
448                 {
449                         if (selection[i].equals(path))
450                                 return true;
451                 }
452                 return false;
453         }
454
455         /**
456          * Checks if the selection is empty.
457          * 
458          * @return <code>true</code> if the selection is empty, <code>false</code>
459          *         otherwise
460          */
461         public boolean isSelectionEmpty()
462         {
463                 return ((selection == null) || (selection.length == 0));
464         }
465
466         /**
467          * Removes all paths from the selection.
468          */
469         public void clearSelection()
470         {
471                 leadPath = null;
472                 selection = null;
473         }
474
475         /**
476          * Adds a <code>TreeSelectionListener</code> object to this model.
477          * 
478          * @param listener the listener to add
479          */
480         public void addTreeSelectionListener(TreeSelectionListener listener)
481         {
482                 listenerList.add(TreeSelectionListener.class, listener);
483         }
484
485         /**
486          * Removes a <code>TreeSelectionListener</code> object from this model.
487          * 
488          * @param listener the listener to remove
489          */
490         public void removeTreeSelectionListener(TreeSelectionListener listener)
491         {
492                 listenerList.remove(TreeSelectionListener.class, listener);
493         }
494
495         /**
496          * Returns all <code>TreeSelectionListener</code> added to this model.
497          * 
498          * @return an array of listeners
499          * 
500          * @since 1.4
501          */
502         public TreeSelectionListener[] getTreeSelectionListeners()
503         {
504                 return (TreeSelectionListener[]) 
505                                 getListeners(TreeSelectionListener.class);
506         }
507
508         /**
509          * fireValueChanged
510          * 
511          * @param event the event to fire.
512          */
513         protected void fireValueChanged(TreeSelectionEvent event)
514         {
515                 TreeSelectionListener[] listeners = getTreeSelectionListeners();
516
517                 for (int i = 0; i < listeners.length; ++i)
518                         listeners[i].valueChanged(event);
519         }
520
521         /**
522          * Returns all added listeners of a special type.
523          * 
524          * @param listenerType the listener type
525          * 
526          * @return an array of listeners
527          * 
528          * @since 1.3
529          */
530         public EventListener[] getListeners(Class listenerType)
531         {
532                 return listenerList.getListeners(listenerType);
533         }
534
535         /**
536          * Returns the currently selected rows.
537          * 
538          * @return the currently selected rows
539          */
540         public int[] getSelectionRows()
541         {
542                 if (rowMapper == null)
543                         return null;
544                 else
545                         return rowMapper.getRowsForPaths(selection);
546         }
547
548         /**
549          * Returns the smallest row index from the selection.
550          * 
551          * @return the smallest row index from the selection
552          */
553         public int getMinSelectionRow()
554         {
555                 if ((rowMapper == null) || (selection == null)
556                                 || (selection.length == 0))
557                         return -1;
558                 else
559                 {
560                         int[] rows = rowMapper.getRowsForPaths(selection);
561                         int minRow = Integer.MAX_VALUE;
562                         for (int index = 0; index < rows.length; index++)
563                                 minRow = Math.min(minRow, rows[index]);
564                         return minRow;
565                 }
566         }
567
568         /**
569          * Returns the largest row index from the selection.
570          * 
571          * @return the largest row index from the selection
572          */
573         public int getMaxSelectionRow()
574         {
575                 if ((rowMapper == null) || (selection == null)
576                                 || (selection.length == 0))
577                         return -1;
578                 else
579                 {
580                         int[] rows = rowMapper.getRowsForPaths(selection);
581                         int maxRow = -1;
582                         for (int index = 0; index < rows.length; index++)
583                                 maxRow = Math.max(maxRow, rows[index]);
584                         return maxRow;
585                 }
586         }
587
588         /**
589          * Checks if a particular row is selected.
590          * 
591          * @param row the index of the row to check
592          * 
593          * @return <code>true</code> if the row is in this selection,
594          *         <code>false</code> otherwise
595          */
596         public boolean isRowSelected(int row)
597         {
598                 return false; // TODO
599         }
600
601         /**
602          * Updates the mappings from TreePaths to row indices.
603          */
604         public void resetRowSelection()
605         {
606                 // TODO
607         }
608
609         /**
610          * getLeadSelectionRow
611          * 
612          * @return int
613          */
614         public int getLeadSelectionRow()
615         {
616                 if ((rowMapper == null) || (leadPath == null))
617                         return -1;
618                 else
619                         return rowMapper.getRowsForPaths(new TreePath[] {
620                                 leadPath })[0];
621         }
622
623         /**
624          * getLeadSelectionPath
625          * 
626          * @return TreePath
627          */
628         public TreePath getLeadSelectionPath()
629         {
630                 return leadPath;
631         }
632
633         /**
634          * Adds a <code>PropertyChangeListener</code> object to this model.
635          * 
636          * @param listener the listener to add.
637          */
638         public void addPropertyChangeListener(PropertyChangeListener listener)
639         {
640                 changeSupport.addPropertyChangeListener(listener);
641         }
642
643         /**
644          * Removes a <code>PropertyChangeListener</code> object from this model.
645          * 
646          * @param listener the listener to remove.
647          */
648         public void removePropertyChangeListener(PropertyChangeListener listener)
649         {
650                 changeSupport.removePropertyChangeListener(listener);
651         }
652
653         /**
654          * Returns all added <code>PropertyChangeListener</code> objects.
655          * 
656          * @return an array of listeners.
657          * 
658          * @since 1.4
659          */
660         public PropertyChangeListener[] getPropertyChangeListeners()
661         {
662                 return changeSupport.getPropertyChangeListeners();
663         }
664
665         /**
666          * Makes sure the currently selected paths are valid according to the
667          * current selectionMode.
668          * 
669          * If the selectionMode is set to {@link #CONTIGUOUS_TREE_SELECTION} and the
670          * selection isn't contiguous then the selection is reset to the first set
671          * of contguous paths.
672          * 
673          * If the selectionMode is set to {@link #SINGLE_TREE_SELECTION} and the
674          * selection has more than one path, the selection is reset to the contain
675          * only the first path.
676          */
677         protected void insureRowContinuity()
678         {
679                 // TODO
680         }
681
682         /**
683          * Returns <code>true</code> if the paths are contiguous or we have no
684          * RowMapper assigned.
685          * 
686          * @param paths the paths to check for continuity
687          * @return <code>true</code> if the paths are contiguous or we have no
688          *         RowMapper assigned
689          */
690         protected boolean arePathsContiguous(TreePath[] paths)
691         {
692                 return false; // TODO
693         }
694
695         /**
696          * Checks if the paths can be added. This returns <code>true</code> if:
697          * <ul>
698          * <li><code>paths</code> is <code>null</code> or empty</li>
699          * <li>we have no RowMapper assigned</li>
700          * <li>nothing is currently selected</li>
701          * <li>selectionMode is {@link #DISCONTIGUOUS_TREE_SELECTION}</li>
702          * <li>adding the paths to the selection still results in a contiguous set
703          * of paths</li>
704          * 
705          * @param paths the paths to check
706          * 
707          * @return <code>true</code> if the paths can be added with respect to the
708          *         selectionMode
709          */
710         protected boolean canPathsBeAdded(TreePath[] paths)
711         {
712                 return false; // TODO
713         }
714
715         /**
716          * Checks if the paths can be removed without breaking the continuity of the
717          * selection according to selectionMode.
718          * 
719          * @param paths the paths to check
720          * @return <code>true</code> if the paths can be removed with respect to
721          *         the selectionMode
722          */
723         protected boolean canPathsBeRemoved(TreePath[] paths)
724         {
725                 return false; // TODO
726         }
727
728         /**
729          * notifyPathChange
730          * 
731          * @param value0 TODO
732          * @param value1 TODO
733          */
734         protected void notifyPathChange(Vector value0, TreePath value1)
735         {
736                 // TODO
737         }
738
739         /**
740          * Updates the lead index instance field.
741          */
742         protected void updateLeadIndex()
743         {
744                 // TODO
745         }
746
747         /**
748          * Deprecated and not used.
749          */
750         protected void insureUniqueness()
751         {
752                 // TODO
753         }
754 }