TreeUi: initial selection (on maybeReady handler)
[fedora-idea.git] / platform / platform-api / src / com / intellij / ide / util / treeView / AbstractTreeBuilder.java
blobbe66d05648d013879b16841ccd8fd05388f82b6c
1 /*
2 * Copyright 2000-2007 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.ide.util.treeView;
19 import com.intellij.ide.projectView.PresentationData;
20 import com.intellij.openapi.Disposable;
21 import com.intellij.openapi.application.Application;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.progress.ProgressIndicator;
24 import com.intellij.openapi.util.ActionCallback;
25 import com.intellij.util.containers.HashSet;
26 import com.intellij.util.ui.UIUtil;
27 import org.jetbrains.annotations.NotNull;
28 import org.jetbrains.annotations.Nullable;
30 import javax.swing.*;
31 import javax.swing.tree.DefaultMutableTreeNode;
32 import javax.swing.tree.DefaultTreeModel;
33 import javax.swing.tree.TreePath;
34 import java.lang.ref.WeakReference;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.Comparator;
38 import java.util.Set;
40 public class AbstractTreeBuilder implements Disposable {
41 private AbstractTreeUi myUi;
42 private static final String TREE_BUILDER = "TreeBuilder";
44 public AbstractTreeBuilder(JTree tree,
45 DefaultTreeModel treeModel,
46 AbstractTreeStructure treeStructure,
47 @Nullable Comparator<NodeDescriptor> comparator) {
48 init(tree, treeModel, treeStructure, comparator, true);
50 public AbstractTreeBuilder(JTree tree,
51 DefaultTreeModel treeModel,
52 AbstractTreeStructure treeStructure,
53 @Nullable Comparator<NodeDescriptor> comparator,
54 boolean updateIfInactive) {
55 init(tree, treeModel, treeStructure, comparator, updateIfInactive);
58 protected AbstractTreeBuilder() {
62 protected void init(final JTree tree, final DefaultTreeModel treeModel, final AbstractTreeStructure treeStructure, final @Nullable Comparator<NodeDescriptor> comparator) {
64 myUi = createUi();
65 getUi().init(this, tree, treeModel, treeStructure, comparator);
67 protected void init(final JTree tree, final DefaultTreeModel treeModel, final AbstractTreeStructure treeStructure, final @Nullable Comparator<NodeDescriptor> comparator,
68 final boolean updateIfInactive) {
70 tree.putClientProperty(TREE_BUILDER, new WeakReference(this));
72 myUi = createUi();
73 getUi().init(this, tree, treeModel, treeStructure, comparator, updateIfInactive);
76 protected AbstractTreeUi createUi() {
77 return new AbstractTreeUi();
80 public final void select(final Object element) {
81 select(element, null);
84 public final void select(final Object element, @Nullable final Runnable onDone) {
85 getUi().select(element, onDone);
88 public final void select(final Object element, @Nullable final Runnable onDone, boolean addToSelection) {
89 getUi().select(element, onDone, addToSelection);
92 public final void expand(Object element, @Nullable Runnable onDone) {
93 getUi().expand(element, onDone);
96 public final void collapseChildren(Object element, @Nullable Runnable onDone) {
97 getUi().collapseChildren(element, onDone);
100 public final void select(final Object[] elements, @Nullable final Runnable onDone) {
101 getUi().select(elements, onDone);
104 public final void select(final Object[] elements, @Nullable final Runnable onDone, boolean addToSelection) {
105 getUi().select(elements, onDone, addToSelection);
108 protected AbstractTreeNode createSearchingTreeNodeWrapper() {
109 return new AbstractTreeNodeWrapper();
112 public final AbstractTreeBuilder setClearOnHideDelay(final long clearOnHideDelay) {
113 getUi().setClearOnHideDelay(clearOnHideDelay);
114 return this;
117 protected AbstractTreeUpdater createUpdater() {
118 return new AbstractTreeUpdater(this);
121 protected final AbstractTreeUpdater getUpdater() {
122 return getUi().getUpdater();
125 public final boolean addSubtreeToUpdateByElement(Object element) {
126 return getUpdater().addSubtreeToUpdateByElement(element);
129 public final void addSubtreeToUpdate(DefaultMutableTreeNode node) {
130 getUi().addSubtreeToUpdate(node);
133 public final void addSubtreeToUpdate(DefaultMutableTreeNode node, Runnable afterUpdate) {
134 getUi().addSubtreeToUpdate(node, afterUpdate);
137 public final DefaultMutableTreeNode getRootNode() {
138 return getUi().getRootNode();
141 public final void setNodeDescriptorComparator(Comparator<NodeDescriptor> nodeDescriptorComparator) {
142 getUi().setNodeDescriptorComparator(nodeDescriptorComparator);
146 * node descriptor getElement contract is as follows:
147 * 1.TreeStructure always returns & recieves "treestructure" element returned by getTreeStructureElement
148 * 2.Paths contain "model" element returned by getElement
151 protected Object getTreeStructureElement(NodeDescriptor nodeDescriptor) {
152 return nodeDescriptor.getElement();
156 protected void updateNode(final DefaultMutableTreeNode node) {
157 getUi().doUpdateNode(node);
160 protected boolean validateNode(final Object child) {
161 return true;
164 protected boolean isDisposeOnCollapsing(NodeDescriptor nodeDescriptor) {
165 return true;
168 public final JTree getTree() {
169 return getUi().getTree();
172 public final AbstractTreeStructure getTreeStructure() {
173 return getUi().getTreeStructure();
176 public final void setTreeStructure(final AbstractTreeStructure structure) {
177 getUi().setTreeStructure(structure);
180 public void updateFromRoot() {
181 getUi().doUpdateFromRoot();
184 protected ActionCallback updateFromRootCB() {
185 return getUi().doUpdateFromRootCB();
188 public void initRootNode() {
189 getUi().initRootNode();
193 * @deprecated
194 * @param element
196 public void buildNodeForElement(Object element) {
197 getUi().buildNodeForElement(element);
201 * @deprecated
202 * @param element
203 * @return
205 @Nullable
206 public DefaultMutableTreeNode getNodeForElement(Object element) {
207 return getUi().getNodeForElement(element, false);
210 public void cleanUp() {
211 getUi().doCleanUp();
214 @Nullable
215 protected ProgressIndicator createProgressIndicator() {
216 return null;
219 protected void expandNodeChildren(final DefaultMutableTreeNode node) {
220 getUi().doExpandNodeChildren(node);
223 protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
224 return getTreeStructure().getRootElement() == getTreeStructureElement(nodeDescriptor);
227 protected boolean isAlwaysShowPlus(final NodeDescriptor descriptor) {
228 return false;
233 protected boolean isSmartExpand() {
234 return true;
237 public final boolean isDisposed() {
238 return getUi() == null || getUi().isReleased();
242 * @deprecated
243 * @param node
245 public final void updateSubtree(final DefaultMutableTreeNode node) {
246 getUi().updateSubtree(node);
249 public final boolean wasRootNodeInitialized() {
250 return getUi().wasRootNodeInitialized();
253 public final boolean isNodeBeingBuilt(final TreePath path) {
254 return getUi().isNodeBeingBuilt(path);
258 * @deprecated
259 * @param path
261 public final void buildNodeForPath(final Object[] path) {
262 getUi().buildNodeForPath(path);
266 * @deprecated
268 public final DefaultMutableTreeNode getNodeForPath(final Object[] path) {
269 return getUi().getNodeForPath(path);
272 protected Object findNodeByElement(final Object element) {
273 return getUi().findNodeByElement(element);
276 public static boolean isLoadingNode(final DefaultMutableTreeNode node) {
277 return AbstractTreeUi.isLoadingNode(node);
280 public boolean isChildrenResortingNeeded(NodeDescriptor descriptor) {
281 return true;
284 protected void runOnYeildingDone(Runnable onDone) {
285 UIUtil.invokeLaterIfNeeded(onDone);
288 protected void yield(Runnable runnable) {
289 SwingUtilities.invokeLater(runnable);
292 public boolean isToYieldUpdateFor(DefaultMutableTreeNode node) {
293 return true;
296 public boolean isToEnsureSelectionOnFocusGained() {
297 return true;
300 protected void runBackgroundLoading(final Runnable runnable) {
301 final Application app = ApplicationManager.getApplication();
302 if (app != null) {
303 app.runReadAction(new Runnable() {
304 public void run() {
305 runnable.run();
308 } else {
309 runnable.run();
313 protected void updateAfterLoadedInBackground(Runnable runnable) {
314 UIUtil.invokeLaterIfNeeded(runnable);
317 public static class AbstractTreeNodeWrapper extends AbstractTreeNode<Object> {
318 public AbstractTreeNodeWrapper() {
319 super(null, null);
322 @NotNull
323 public Collection<AbstractTreeNode> getChildren() {
324 return Collections.emptyList();
327 public void update(PresentationData presentation) {
331 public final AbstractTreeUi getUi() {
332 return myUi;
335 public void dispose() {
336 if (isDisposed()) return;
338 myUi.release();
339 myUi = null;
342 protected boolean updateNodeDescriptor(final NodeDescriptor descriptor) {
343 return getUi().doUpdateNodeDescriptor(descriptor);
346 public final DefaultTreeModel getTreeModel() {
347 return (DefaultTreeModel)getTree().getModel();
350 @NotNull
351 public final Set<Object> getSelectedElements() {
352 return getUi().getSelectedElements();
355 @NotNull
356 public final <T> Set<T> getSelectedElements(Class<T> elementClass) {
357 Set<T> result = new HashSet<T>();
358 for (Object o : getSelectedElements()) {
359 Object each = transformElement(o);
360 if (elementClass.isInstance(each)) {
361 //noinspection unchecked
362 result.add((T) each);
365 return result;
368 protected Object transformElement(Object object) {
369 return object;
372 public final void setCanYieldUpdate(boolean yield) {
373 getUi().setCanYield(yield);
376 @Nullable
377 public static AbstractTreeBuilder getBuilderFor(JTree tree) {
378 final WeakReference ref = (WeakReference)tree.getClientProperty(TREE_BUILDER);
379 return ref != null ? (AbstractTreeBuilder)ref.get() : null;
382 @Nullable
383 public final <T> Object accept(Class nodeClass, TreeVisitor<T> visitor) {
384 return accept(nodeClass, getTreeStructure().getRootElement(), visitor);
387 @Nullable
388 private <T> Object accept(Class nodeClass, Object element, TreeVisitor<T> visitor) {
389 if (element == null) return null;
391 if (nodeClass.isAssignableFrom(element.getClass())) {
392 if (visitor.visit((T)element)) return element;
395 final Object[] children = getTreeStructure().getChildElements(element);
396 for (Object each : children) {
397 final Object childObject = accept(nodeClass, each, visitor);
398 if (childObject != null) return childObject;
401 return null;
404 public <T> boolean select(Class nodeClass, TreeVisitor<T> visitor, @Nullable Runnable onDone, boolean addToSelection) {
405 final Object element = accept(nodeClass, visitor);
406 if (element != null) {
407 getUi().select(element, onDone, addToSelection);
408 return true;
411 return false;