Merge from the pain train
[official-gcc.git] / libjava / javax / swing / JTree.java
blob170fd3014b2fc937a0e9939ba05cd881d5dd6c07
1 /* JTree.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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;
41 import java.awt.Dimension;
42 import java.awt.Rectangle;
43 import java.util.Enumeration;
44 import java.util.Hashtable;
45 import java.util.Iterator;
46 import java.util.Vector;
48 import javax.accessibility.Accessible;
49 import javax.accessibility.AccessibleContext;
50 import javax.swing.event.TreeExpansionEvent;
51 import javax.swing.event.TreeExpansionListener;
52 import javax.swing.event.TreeSelectionEvent;
53 import javax.swing.event.TreeSelectionListener;
54 import javax.swing.event.TreeWillExpandListener;
55 import javax.swing.plaf.TreeUI;
56 import javax.swing.tree.DefaultMutableTreeNode;
57 import javax.swing.tree.DefaultTreeCellRenderer;
58 import javax.swing.tree.DefaultTreeModel;
59 import javax.swing.tree.ExpandVetoException;
60 import javax.swing.tree.TreeCellEditor;
61 import javax.swing.tree.TreeCellRenderer;
62 import javax.swing.tree.TreeModel;
63 import javax.swing.tree.TreeNode;
64 import javax.swing.tree.TreePath;
65 import javax.swing.tree.TreeSelectionModel;
68 public class JTree extends JComponent
69 implements Scrollable, Accessible
71 private static final long serialVersionUID = 7559816092864483649L;
73 public static final String CELL_EDITOR_PROPERTY = "cellEditor";
74 public static final String CELL_RENDERER_PROPERTY = "cellRenderer";
75 public static final String EDITABLE_PROPERTY = "editable";
76 public static final String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing";
77 public static final String LARGE_MODEL_PROPERTY = "largeModel";
78 public static final String ROOT_VISIBLE_PROPERTY = "rootVisible";
79 public static final String ROW_HEIGHT_PROPERTY = "rowHeight";
80 public static final String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand";
81 public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
82 public static final String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles";
83 public static final String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount";
84 public static final String TREE_MODEL_PROPERTY = "model";
85 public static final String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount";
87 /** @since 1.3 */
88 public static final String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath";
89 /** @since 1.3 */
90 public static final String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath";
91 /** @since 1.3 */
92 public static final String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths";
94 private static final Object EXPANDED = new Object();
95 private static final Object COLLAPSED = new Object();
97 private boolean dragEnabled;
98 private boolean expandsSelectedPaths;
99 private TreePath anchorSelectionPath;
100 private TreePath leadSelectionPath;
103 * This contains the state of all nodes in the tree. Al/ entries map the
104 * TreePath of a note to to its state. Valid states are EXPANDED and
105 * COLLAPSED. Nodes not in this Hashtable are assumed state COLLAPSED.
107 private Hashtable nodeStates;
109 protected transient TreeCellEditor cellEditor;
110 protected transient TreeCellRenderer cellRenderer;
111 protected boolean editable;
112 protected boolean invokesStopCellEditing;
113 protected boolean largeModel;
114 protected boolean rootVisible;
115 protected int rowHeight;
116 protected boolean scrollsOnExpand;
117 protected transient TreeSelectionModel selectionModel;
118 protected boolean showsRootHandles;
119 protected int toggleClickCount;
120 protected transient TreeModel treeModel;
121 protected int visibleRowCount;
124 * Creates a new <code>JTree</code> object.
126 public JTree()
128 this(createTreeModel(null));
132 * Creates a new <code>JTree</code> object.
134 * @param value the initial nodes in the tree
136 public JTree(Hashtable value)
138 this(createTreeModel(value));
142 * Creates a new <code>JTree</code> object.
144 * @param value the initial nodes in the tree
146 public JTree(Object[] value)
148 this(createTreeModel(value));
152 * Creates a new <code>JTree</code> object.
154 * @param model the model to use
156 public JTree(TreeModel model)
158 treeModel = model;
159 setCellRenderer(new DefaultTreeCellRenderer());
160 updateUI();
164 * Creates a new <code>JTree</code> object.
166 * @param root the root node
168 public JTree(TreeNode root)
170 this(root, false);
174 * Creates a new <code>JTree</code> object.
176 * @param root the root node
177 * @param asksAllowChildren if false, all nodes without children are leaf nodes.
178 * If true, only nodes that do not allow children are leaf nodes.
180 public JTree(TreeNode root, boolean asksAllowChildren)
182 this(new DefaultTreeModel(root, asksAllowChildren));
186 * Creates a new <code>JTree</code> object.
188 * @param value the initial nodes in the tree
190 public JTree(Vector value)
192 this(createTreeModel(value));
195 public static class DynamicUtilTreeNode
196 extends DefaultMutableTreeNode
198 protected Object childValue;
199 protected boolean loadedChildren;
202 * Currently not set or used by this class.
203 * It might be set and used in later versions of this class.
205 protected boolean hasChildren;
207 public DynamicUtilTreeNode(Object value,
208 Object children)
210 super(value);
211 childValue = children;
212 loadedChildren = false;
215 public int getChildCount()
217 loadChildren();
218 return super.getChildCount();
221 protected void loadChildren()
223 if (!loadedChildren)
225 createChildren(this, childValue);
226 loadedChildren = true;
230 public Enumeration children()
232 loadChildren();
233 return super.children();
236 public boolean isLeaf()
238 return (childValue == null ||
239 !(childValue instanceof Hashtable
240 || childValue instanceof Vector
241 || childValue.getClass().isArray()));
244 public static void createChildren(DefaultMutableTreeNode parent,
245 Object children)
247 if (children instanceof Hashtable)
249 Hashtable tab = (Hashtable) children;
250 Enumeration e = tab.keys();
251 while (e.hasMoreElements())
253 Object key = e.nextElement();
254 Object val = tab.get(key);
255 parent.add(new DynamicUtilTreeNode(key, val));
258 else if (children instanceof Vector)
260 Iterator i = ((Vector)children).iterator();
261 while (i.hasNext())
263 Object n = i.next();
264 parent.add(new DynamicUtilTreeNode(n,n));
267 else if (children.getClass().isArray())
269 Object[] arr = (Object[]) children;
270 for (int i = 0; i < arr.length; ++i)
271 parent.add(new DynamicUtilTreeNode(arr[i], arr[i]));
276 public int getRowForPath(TreePath path)
278 TreeUI ui = getUI();
280 if (ui != null)
281 return ui.getRowForPath(this, path);
283 return -1;
286 public TreePath getPathForRow(int row)
288 TreeUI ui = getUI();
289 return ui != null ? ui.getPathForRow(this, row) : null;
292 protected TreePath[] getPathBetweenRows(int index0, int index1)
294 TreeUI ui = getUI();
296 if (ui == null)
297 return null;
299 int minIndex = Math.min(index0, index1);
300 int maxIndex = Math.max(index0, index1);
301 TreePath[] paths = new TreePath[maxIndex - minIndex + 1];
303 for (int i = minIndex; i <= maxIndex; ++i)
304 paths[i - minIndex] = ui.getPathForRow(this, i);
306 return paths;
310 * Creates a new <code>TreeModel</code> object.
312 * @param value the values stored in the model
314 protected static TreeModel createTreeModel(Object value)
316 return new DefaultTreeModel(new DynamicUtilTreeNode(value, value));
320 * Return the UI associated with this <code>JTree</code> object.
322 * @return the associated <code>TreeUI</code> object
324 public TreeUI getUI()
326 return (TreeUI) ui;
330 * Sets the UI associated with this <code>JTree</code> object.
332 * @param ui the <code>TreeUI</code> to associate
334 public void setUI(TreeUI ui)
336 super.setUI(ui);
340 * This method resets the UI used to the Look and Feel defaults..
342 public void updateUI()
344 setUI((TreeUI) UIManager.getUI(this));
345 revalidate();
346 repaint();
350 * This method returns the String ID of the UI class of Separator.
352 * @return The UI class' String ID.
354 public String getUIClassID()
356 return "TreeUI";
360 * Gets the AccessibleContext associated with this <code>JToggleButton</code>.
362 * @return the associated context
364 public AccessibleContext getAccessibleContext()
366 return null;
370 * Returns the preferred viewport size..
372 * @return the preferred size
374 public Dimension getPreferredScrollableViewportSize()
376 return null;
379 public int getScrollableUnitIncrement(Rectangle visibleRect,
380 int orientation, int direction)
382 return 1;
385 public int getScrollableBlockIncrement(Rectangle visibleRect,
386 int orientation, int direction)
388 return 1;
391 public boolean getScrollableTracksViewportWidth()
393 return false;
396 public boolean getScrollableTracksViewportHeight()
398 return false;
402 * Adds a <code>TreeExpansionListener</code> object to the tree.
404 * @param listener the listener to add
406 public void addTreeExpansionListener(TreeExpansionListener listener)
408 listenerList.add(TreeExpansionListener.class, listener);
412 * Removes a <code>TreeExpansionListener</code> object from the tree.
414 * @param listener the listener to remove
416 public void removeTreeExpansionListener(TreeExpansionListener listener)
418 listenerList.remove(TreeExpansionListener.class, listener);
422 * Returns all added <code>TreeExpansionListener</code> objects.
424 * @return an array of listeners
426 public TreeExpansionListener[] getTreeExpansionListeners()
428 return (TreeExpansionListener[]) getListeners(TreeExpansionListener.class);
432 * Notifies all listeners that the tree was collapsed.
434 * @param path the path to the node that was collapsed
436 public void fireTreeCollapsed(TreePath path)
438 TreeExpansionEvent event = new TreeExpansionEvent(this, path);
439 TreeExpansionListener[] listeners = getTreeExpansionListeners();
441 for (int index = 0; index < listeners.length; ++index)
442 listeners[index].treeCollapsed(event);
446 * Notifies all listeners that the tree was expanded.
448 * @param path the path to the node that was expanded
450 public void fireTreeExpanded(TreePath path)
452 TreeExpansionEvent event = new TreeExpansionEvent(this, path);
453 TreeExpansionListener[] listeners = getTreeExpansionListeners();
455 for (int index = 0; index < listeners.length; ++index)
456 listeners[index].treeExpanded(event);
460 * Adds a <code>TreeSelctionListener</code> object to the tree.
462 * @param listener the listener to add
464 public void addTreeSelectionListener(TreeSelectionListener listener)
466 listenerList.add(TreeSelectionListener.class, listener);
470 * Removes a <code>TreeSelectionListener</code> object from the tree.
472 * @param listener the listener to remove
474 public void removeTreeSelectionListener(TreeSelectionListener listener)
476 listenerList.remove(TreeSelectionListener.class, listener);
480 * Returns all added <code>TreeSelectionListener</code> objects.
482 * @return an array of listeners
484 public TreeSelectionListener[] getTreeSelectionListeners()
486 return (TreeSelectionListener[]) getListeners(TreeSelectionListener.class);
490 * Notifies all listeners when the selection of the tree changed.
492 * @param event the event to send
494 protected void fireValueChanged(TreeSelectionEvent event)
496 TreeSelectionListener[] listeners = getTreeSelectionListeners();
498 for (int index = 0; index < listeners.length; ++index)
499 listeners[index].valueChanged(event);
503 * Adds a <code>TreeWillExpandListener</code> object to the tree.
505 * @param listener the listener to add
507 public void addTreeWillExpandListener(TreeWillExpandListener listener)
509 listenerList.add(TreeWillExpandListener.class, listener);
513 * Removes a <code>TreeWillExpandListener</code> object from the tree.
515 * @param listener the listener to remove
517 public void removeTreeWillExpandListener(TreeWillExpandListener listener)
519 listenerList.remove(TreeWillExpandListener.class, listener);
523 * Returns all added <code>TreeWillExpandListener</code> objects.
525 * @return an array of listeners
527 public TreeWillExpandListener[] getTreeWillExpandListeners()
529 return (TreeWillExpandListener[]) getListeners(TreeWillExpandListener.class);
533 * Notifies all listeners that the tree will collapse.
535 * @param path the path to the node that will collapse
537 public void fireTreeWillCollapse(TreePath path)
538 throws ExpandVetoException
540 TreeExpansionEvent event = new TreeExpansionEvent(this, path);
541 TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
543 for (int index = 0; index < listeners.length; ++index)
544 listeners[index].treeWillCollapse(event);
548 * Notifies all listeners that the tree will expand.
550 * @param path the path to the node that will expand
552 public void fireTreeWillExpand(TreePath path)
553 throws ExpandVetoException
555 TreeExpansionEvent event = new TreeExpansionEvent(this, path);
556 TreeWillExpandListener[] listeners = getTreeWillExpandListeners();
558 for (int index = 0; index < listeners.length; ++index)
559 listeners[index].treeWillExpand(event);
563 * Returns the model of this <code>JTree</code> object.
565 * @return the associated <code>TreeModel</code>
567 public TreeModel getModel()
569 return treeModel;
573 * Sets the model to use in <code>JTree</code>.
575 * @param model the <code>TreeModel</code> to use
577 public void setModel(TreeModel model)
579 if (treeModel == model)
580 return;
582 TreeModel oldValue = treeModel;
583 treeModel = model;
584 firePropertyChange(TREE_MODEL_PROPERTY, oldValue, model);
588 * Checks if this <code>JTree</code> object is editable.
590 * @return <code>true</code> if this tree object is editable,
591 * <code>false</code> otherwise
593 public boolean isEditable()
595 return editable;
599 * Sets the <code>editable</code> property.
601 * @param flag <code>true</code> to make this tree object editable,
602 * <code>false</code> otherwise
604 public void setEditable(boolean flag)
606 if (editable == flag)
607 return;
609 boolean oldValue = editable;
610 editable = flag;
611 firePropertyChange(EDITABLE_PROPERTY, oldValue, editable);
615 * Checks if the root element is visible.
617 * @return <code>true</code> if the root element is visible,
618 * <code>false</code> otherwise
620 public boolean isRootVisible()
622 return rootVisible;
625 public void setRootVisible(boolean flag)
627 if (rootVisible == flag)
628 return;
630 boolean oldValue = rootVisible;
631 rootVisible = flag;
632 firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, flag);
635 public boolean getShowsRootHandles()
637 return showsRootHandles;
640 public void setShowsRootHandles(boolean flag)
642 if (showsRootHandles == flag)
643 return;
645 boolean oldValue = showsRootHandles;
646 showsRootHandles = flag;
647 firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue, flag);
650 public TreeCellEditor getCellEditor()
652 return cellEditor;
655 public void setCellEditor(TreeCellEditor editor)
657 if (cellEditor == editor)
658 return;
660 TreeCellEditor oldValue = cellEditor;
661 cellEditor = editor;
662 firePropertyChange(CELL_EDITOR_PROPERTY, oldValue, editor);
665 public TreeCellRenderer getCellRenderer()
667 return cellRenderer;
670 public void setCellRenderer(TreeCellRenderer newRenderer)
672 if (cellRenderer == newRenderer)
673 return;
675 TreeCellRenderer oldValue = cellRenderer;
676 cellRenderer = newRenderer;
677 firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, newRenderer);
680 public TreeSelectionModel getSelectionModel()
682 return selectionModel;
685 public void setSelectionModel(TreeSelectionModel model)
687 if (selectionModel == model)
688 return;
690 TreeSelectionModel oldValue = selectionModel;
691 selectionModel = model;
692 firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue, model);
695 public int getVisibleRowCount()
697 return visibleRowCount;
700 public void setVisibleRowCount(int rows)
702 if (visibleRowCount == rows)
703 return;
705 int oldValue = visibleRowCount;
706 visibleRowCount = rows;
707 firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldValue, rows);
710 public boolean isLargeModel()
712 return largeModel;
715 public void setLargeModel(boolean large)
717 if (largeModel == large)
718 return;
720 boolean oldValue = largeModel;
721 largeModel = large;
722 firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, large);
725 public int getRowHeight()
727 return rowHeight;
730 public void setRowHeight(int height)
732 if (rowHeight == height)
733 return;
735 int oldValue = rowHeight;
736 rowHeight = height;
737 firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, height);
740 public boolean isFixedRowHeight()
742 return rowHeight > 0;
745 public boolean getInvokesStopCellEditing()
747 return invokesStopCellEditing;
750 public void setInvokesStopCellEditing(boolean invoke)
752 if (invokesStopCellEditing == invoke)
753 return;
755 boolean oldValue = invokesStopCellEditing;
756 invokesStopCellEditing = invoke;
757 firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY, oldValue, invoke);
761 * @since 1.3
763 public int getToggleClickCount()
765 return toggleClickCount;
769 * @since 1.3
771 public void setToggleClickCount(int count)
773 if (toggleClickCount == count)
774 return;
776 int oldValue = toggleClickCount;
777 toggleClickCount = count;
778 firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldValue, count);
781 public void scrollPathToVisible(TreePath path)
783 if (path == null)
784 return;
786 Rectangle rect = getPathBounds(path);
788 if (rect == null)
789 return;
791 scrollRectToVisible(rect);
794 public void scrollRowToVisible(int row)
796 scrollPathToVisible(getPathForRow(row));
799 public boolean getScrollsOnExpand()
801 return scrollsOnExpand;
804 public void setScrollsOnExpand(boolean scroll)
806 if (scrollsOnExpand == scroll)
807 return;
809 boolean oldValue = scrollsOnExpand;
810 scrollsOnExpand = scroll;
811 firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue, scroll);
814 public void setSelectionPath(TreePath path)
816 selectionModel.setSelectionPath(path);
819 public void setSelectionPaths(TreePath[] paths)
821 selectionModel.setSelectionPaths(paths);
824 public void setSelectionRow(int row)
826 TreePath path = getPathForRow(row);
828 if (path != null)
829 selectionModel.setSelectionPath(path);
832 public void setSelectionRows(int[] rows)
834 // Make sure we have an UI so getPathForRow() does not return null.
835 if (rows == null || getUI() == null)
836 return;
838 TreePath[] paths = new TreePath[rows.length];
840 for (int i = rows.length - 1; i >= 0; --i)
841 paths[i] = getPathForRow(rows[i]);
843 setSelectionPaths(paths);
846 public void setSelectionInterval(int index0, int index1)
848 TreePath[] paths = getPathBetweenRows(index0, index1);
850 if (paths != null)
851 setSelectionPaths(paths);
854 public void addSelectionPath(TreePath path)
856 selectionModel.addSelectionPath(path);
859 public void addSelectionPaths(TreePath[] paths)
861 selectionModel.addSelectionPaths(paths);
864 public void addSelectionRow(int row)
866 TreePath path = getPathForRow(row);
868 if (path != null)
869 selectionModel.addSelectionPath(path);
872 public void addSelectionRows(int[] rows)
874 // Make sure we have an UI so getPathForRow() does not return null.
875 if (rows == null || getUI() == null)
876 return;
878 TreePath[] paths = new TreePath[rows.length];
880 for (int i = rows.length - 1; i >= 0; --i)
881 paths[i] = getPathForRow(rows[i]);
883 addSelectionPaths(paths);
886 public void addSelectionInterval(int index0, int index1)
888 TreePath[] paths = getPathBetweenRows(index0, index1);
890 if (paths != null)
891 addSelectionPaths(paths);
894 public void removeSelectionPath(TreePath path)
896 selectionModel.removeSelectionPath(path);
899 public void removeSelectionPaths(TreePath[] paths)
901 selectionModel.removeSelectionPaths(paths);
904 public void removeSelectionRow(int row)
906 TreePath path = getPathForRow(row);
908 if (path != null)
909 selectionModel.removeSelectionPath(path);
912 public void removeSelectionRows(int[] rows)
914 // Make sure we have an UI so getPathForRow() does not return null.
915 if (rows == null || getUI() == null)
916 return;
918 TreePath[] paths = new TreePath[rows.length];
920 for (int i = rows.length - 1; i >= 0; --i)
921 paths[i] = getPathForRow(rows[i]);
923 removeSelectionPaths(paths);
926 public void removeSelectionInterval(int index0, int index1)
928 TreePath[] paths = getPathBetweenRows(index0, index1);
930 if (paths != null)
931 removeSelectionPaths(paths);
934 public void clearSelection()
936 selectionModel.clearSelection();
939 public TreePath getLeadSelectionPath()
941 return leadSelectionPath;
945 * @since 1.3
947 public void setLeadSelectionPath(TreePath path)
949 if (leadSelectionPath == path)
950 return;
952 TreePath oldValue = leadSelectionPath;
953 leadSelectionPath = path;
954 firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, path);
958 * @since 1.3
960 public TreePath getAnchorSelectionPath()
962 return anchorSelectionPath;
966 * @since 1.3
968 public void setAnchorSelectionPath(TreePath path)
970 if (anchorSelectionPath == path)
971 return;
973 TreePath oldValue = anchorSelectionPath;
974 anchorSelectionPath = path;
975 firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, path);
978 public int getLeadSelectionRow()
980 return selectionModel.getLeadSelectionRow();
983 public int getMaxSelectionRow()
985 return selectionModel.getMaxSelectionRow();
988 public int getMinSelectionRow()
990 return selectionModel.getMinSelectionRow();
993 public int getSelectionCount()
995 return selectionModel.getSelectionCount();
998 public TreePath getSelectionPath()
1000 return selectionModel.getSelectionPath();
1003 public TreePath[] getSelectionPaths()
1005 return selectionModel.getSelectionPaths();
1008 public int[] getSelectionRows()
1010 return selectionModel.getSelectionRows();
1013 public boolean isPathSelected(TreePath path)
1015 return selectionModel.isPathSelected(path);
1018 public boolean isRowSelected(int row)
1020 return selectionModel.isRowSelected(row);
1023 public boolean isSelectionEmpty()
1025 return selectionModel.isSelectionEmpty();
1029 * Return the value of the <code>dragEnabled</code> property.
1031 * @return the value
1033 * @since 1.4
1035 public boolean getDragEnabled()
1037 return dragEnabled;
1041 * Set the <code>dragEnabled</code> property.
1043 * @param enabled new value
1045 * @since 1.4
1047 public void setDragEnabled(boolean enabled)
1049 dragEnabled = enabled;
1052 public int getRowCount()
1054 TreeUI ui = getUI();
1056 if (ui != null)
1057 return ui.getRowCount(this);
1059 return 0;
1062 public void collapsePath(TreePath path)
1064 setExpandedState(path, false);
1067 public void collapseRow(int row)
1069 if (row < 0 || row >= getRowCount())
1070 return;
1072 TreePath path = getPathForRow(row);
1074 if (path != null)
1075 collapsePath(path);
1078 public void expandPath(TreePath path)
1080 // Don't expand if last path component is a leaf node.
1081 if ((path == null)
1082 || (treeModel.isLeaf(path.getLastPathComponent())))
1083 return;
1085 setExpandedState(path, true);
1088 public void expandRow(int row)
1090 if (row < 0 || row >= getRowCount())
1091 return;
1093 TreePath path = getPathForRow(row);
1095 if (path != null)
1096 expandPath(path);
1099 public boolean isCollapsed(TreePath path)
1101 return ! isExpanded(path);
1104 public boolean isCollapsed(int row)
1106 if (row < 0 || row >= getRowCount())
1107 return false;
1109 TreePath path = getPathForRow(row);
1111 if (path != null)
1112 return isCollapsed(path);
1114 return false;
1117 public boolean isExpanded(TreePath path)
1119 if (path == null)
1120 return false;
1122 Object state = nodeStates.get(path);
1124 if ((state == null) || (state != EXPANDED))
1125 return false;
1127 TreePath parent = path.getParentPath();
1129 if (parent != null)
1130 return isExpanded(parent);
1132 return true;
1135 public boolean isExpanded(int row)
1137 if (row < 0 || row >= getRowCount())
1138 return false;
1140 TreePath path = getPathForRow(row);
1142 if (path != null)
1143 return isExpanded(path);
1145 return false;
1149 * @since 1.3
1151 public boolean getExpandsSelectedPaths()
1153 return expandsSelectedPaths;
1157 * @since 1.3
1159 public void setExpandsSelectedPaths(boolean flag)
1161 if (expandsSelectedPaths == flag)
1162 return;
1164 boolean oldValue = expandsSelectedPaths;
1165 expandsSelectedPaths = flag;
1166 firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue, flag);
1169 public Rectangle getPathBounds(TreePath path)
1171 TreeUI ui = getUI();
1173 if (ui == null)
1174 return null;
1176 return ui.getPathBounds(this, path);
1179 public Rectangle getRowBounds(int row)
1181 TreePath path = getPathForRow(row);
1183 if (path != null)
1184 return getPathBounds(path);
1186 return null;
1189 public boolean isEditing()
1191 TreeUI ui = getUI();
1193 if (ui != null)
1194 return ui.isEditing(this);
1196 return false;
1199 public boolean stopEditing()
1201 TreeUI ui = getUI();
1203 if (ui != null)
1204 return ui.stopEditing(this);
1206 return false;
1209 public void cancelEditing()
1211 TreeUI ui = getUI();
1213 if (ui != null)
1214 ui.cancelEditing(this);
1217 public void startEditingAtPath(TreePath path)
1219 TreeUI ui = getUI();
1221 if (ui != null)
1222 ui.startEditingAtPath(this, path);
1225 public TreePath getEditingPath()
1227 TreeUI ui = getUI();
1229 if (ui != null)
1230 return ui.getEditingPath(this);
1232 return null;
1235 public TreePath getPathForLocation(int x, int y)
1237 TreePath path = getClosestPathForLocation(x, y);
1239 if (path != null)
1241 Rectangle rect = getPathBounds(path);
1243 if ((rect != null) && rect.contains(x, y))
1244 return path;
1247 return null;
1250 public int getRowForLocation(int x, int y)
1252 TreePath path = getPathForLocation(x, y);
1254 if (path != null)
1255 return getRowForPath(path);
1257 return -1;
1260 public TreePath getClosestPathForLocation(int x, int y)
1262 TreeUI ui = getUI();
1264 if (ui != null)
1265 return ui.getClosestPathForLocation(this, x, y);
1267 return null;
1270 public int getClosestRowForLocation(int x, int y)
1272 TreePath path = getClosestPathForLocation(x, y);
1274 if (path != null)
1275 return getRowForPath(path);
1277 return -1;
1280 public Object getLastSelectedPathComponent()
1282 TreePath path = getSelectionPath();
1284 if (path != null)
1285 return path.getLastPathComponent();
1287 return null;
1290 private void checkExpandParents(TreePath path)
1291 throws ExpandVetoException
1293 TreePath parent = path.getParentPath();
1295 if (parent != null)
1296 checkExpandParents(parent);
1298 fireTreeWillExpand(path);
1301 private void doExpandParents(TreePath path, boolean state)
1303 TreePath parent = path.getParentPath();
1305 if (isExpanded(parent))
1306 return;
1308 if (parent != null)
1309 doExpandParents(parent, false);
1311 nodeStates.put(path, state ? EXPANDED : COLLAPSED);
1314 protected void setExpandedState(TreePath path, boolean state)
1316 if (path == null)
1317 return;
1319 TreePath parent = path.getParentPath();
1323 while (parent != null)
1324 checkExpandParents(parent);
1326 catch (ExpandVetoException e)
1328 // Expansion vetoed.
1329 return;
1332 doExpandParents(path, state);
1335 protected void clearToggledPaths()
1337 nodeStates.clear();
1340 protected Enumeration getDescendantToggledPaths(TreePath parent)
1342 if (parent == null)
1343 return null;
1345 Enumeration nodes = nodeStates.keys();
1346 Vector result = new Vector();
1348 while (nodes.hasMoreElements())
1350 TreePath path = (TreePath) nodes.nextElement();
1352 if (path.isDescendant(parent))
1353 result.addElement(path);
1356 return result.elements();
1359 public boolean hasBeenExpanded(TreePath path)
1361 if (path == null)
1362 return false;
1364 return nodeStates.get(path) != null;
1367 public boolean isVisible(TreePath path)
1369 if (path == null)
1370 return false;
1372 TreePath parent = path.getParentPath();
1374 if (parent == null)
1375 return true; // Is root node.
1377 return isExpanded(parent);
1380 public void makeVisible(TreePath path)
1382 if (path == null)
1383 return;
1385 expandPath(path.getParentPath());
1388 public boolean isPathEditable(TreePath path)
1390 return isEditable();