helper method isEditorActivity
[fedora-idea.git] / platform / platform-api / src / com / intellij / ide / util / treeView / AbstractTreeBuilder.java
blob8e4e5faae76ea1c9549fb13b29f6cf7d1554488e
1 /*
2 * Copyright 2000-2009 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 com.intellij.util.ui.update.MergingUpdateQueue;
28 import org.jetbrains.annotations.NotNull;
29 import org.jetbrains.annotations.Nullable;
31 import javax.swing.*;
32 import javax.swing.tree.DefaultMutableTreeNode;
33 import javax.swing.tree.DefaultTreeModel;
34 import javax.swing.tree.TreeNode;
35 import javax.swing.tree.TreePath;
36 import java.lang.ref.WeakReference;
37 import java.util.*;
39 public class AbstractTreeBuilder implements Disposable {
40 private AbstractTreeUi myUi;
41 private static final String TREE_BUILDER = "TreeBuilder";
42 public static final boolean DEFAULT_UPDATE_INACTIVE = true;
44 public AbstractTreeBuilder(JTree tree,
45 DefaultTreeModel treeModel,
46 AbstractTreeStructure treeStructure,
47 @Nullable Comparator<NodeDescriptor> comparator) {
48 this(tree, treeModel, treeStructure, comparator, DEFAULT_UPDATE_INACTIVE);
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() {
63 protected void init(final JTree tree, final DefaultTreeModel treeModel, final AbstractTreeStructure treeStructure, final @Nullable Comparator<NodeDescriptor> comparator,
64 final boolean updateIfInactive) {
66 tree.putClientProperty(TREE_BUILDER, new WeakReference(this));
68 myUi = createUi();
69 getUi().init(this, tree, treeModel, treeStructure, comparator, updateIfInactive);
71 setPassthroughMode(isUnitTestingMode());
74 protected AbstractTreeUi createUi() {
75 return new AbstractTreeUi();
78 public final void select(final Object element) {
79 getUi().userSelect(new Object[] {element}, null, false, true);
82 public final void select(final Object element, @Nullable final Runnable onDone) {
83 getUi().userSelect(new Object[] {element}, onDone, false, true);
86 public final void select(final Object element, @Nullable final Runnable onDone, boolean addToSelection) {
87 getUi().userSelect(new Object[] {element}, onDone, addToSelection, true);
90 public final void select(final Object[] elements, @Nullable final Runnable onDone) {
91 getUi().userSelect(elements, onDone, false, true);
94 public final void select(final Object[] elements, @Nullable final Runnable onDone, boolean addToSelection) {
95 getUi().userSelect(elements, onDone, addToSelection, true);
98 public final void expand(Object element, @Nullable Runnable onDone) {
99 getUi().expand(element, onDone);
102 public final void expand(Object[] element, @Nullable Runnable onDone) {
103 getUi().expand(element, onDone);
106 public final void collapseChildren(Object element, @Nullable Runnable onDone) {
107 getUi().collapseChildren(element, onDone);
111 protected AbstractTreeNode createSearchingTreeNodeWrapper() {
112 return new AbstractTreeNodeWrapper();
115 public final AbstractTreeBuilder setClearOnHideDelay(final long clearOnHideDelay) {
116 getUi().setClearOnHideDelay(clearOnHideDelay);
117 return this;
120 protected AbstractTreeUpdater createUpdater() {
121 AbstractTreeUpdater updater = new AbstractTreeUpdater(this);
122 updater.setModalityStateComponent(MergingUpdateQueue.ANY_COMPONENT);
123 return updater;
126 protected final AbstractTreeUpdater getUpdater() {
127 return getUi().getUpdater();
130 public final boolean addSubtreeToUpdateByElement(Object element) {
131 return getUpdater().addSubtreeToUpdateByElement(element);
134 public final void addSubtreeToUpdate(DefaultMutableTreeNode node) {
135 getUi().addSubtreeToUpdate(node);
138 public final void addSubtreeToUpdate(DefaultMutableTreeNode node, Runnable afterUpdate) {
139 getUi().addSubtreeToUpdate(node, afterUpdate);
142 public final DefaultMutableTreeNode getRootNode() {
143 return getUi().getRootNode();
146 public final void setNodeDescriptorComparator(Comparator<NodeDescriptor> nodeDescriptorComparator) {
147 getUi().setNodeDescriptorComparator(nodeDescriptorComparator);
151 * node descriptor getElement contract is as follows:
152 * 1.TreeStructure always returns & recieves "treestructure" element returned by getTreeStructureElement
153 * 2.Paths contain "model" element returned by getElement
156 protected Object getTreeStructureElement(NodeDescriptor nodeDescriptor) {
157 return nodeDescriptor.getElement();
161 protected void updateNode(final DefaultMutableTreeNode node) {
162 getUi().doUpdateNode(node);
165 protected boolean validateNode(final Object child) {
166 return true;
169 protected boolean isDisposeOnCollapsing(NodeDescriptor nodeDescriptor) {
170 return true;
173 public final JTree getTree() {
174 return getUi().getTree();
177 public final AbstractTreeStructure getTreeStructure() {
178 return getUi().getTreeStructure();
181 public final void setTreeStructure(final AbstractTreeStructure structure) {
182 getUi().setTreeStructure(structure);
186 * @deprecated
187 * @see #queueUpdateFrom
189 public void updateFromRoot() {
190 queueUpdate();
194 * @deprecated
195 * @see #queueUpdateFrom
197 protected ActionCallback updateFromRootCB() {
198 return queueUpdate();
201 public void initRootNode() {
202 getUi().initRootNode();
205 public final ActionCallback queueUpdate() {
206 return queueUpdateFrom(getTreeStructure().getRootElement(), true);
209 public final ActionCallback queueUpdateFrom(final Object element, final boolean forceResort) {
210 if (forceResort) {
211 getUi().incComparatorStamp();
214 return getUi().queueUpdate(element);
218 * @deprecated
219 * @param element
221 public void buildNodeForElement(Object element) {
222 getUi().buildNodeForElement(element);
226 * @deprecated
227 * @param element
228 * @return
230 @Nullable
231 public DefaultMutableTreeNode getNodeForElement(Object element) {
232 return getUi().getNodeForElement(element, false);
235 public void cleanUp() {
236 getUi().doCleanUp();
239 @Nullable
240 protected ProgressIndicator createProgressIndicator() {
241 return null;
244 protected void expandNodeChildren(final DefaultMutableTreeNode node) {
245 getUi().doExpandNodeChildren(node);
248 protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
249 return getTreeStructure().getRootElement() == getTreeStructureElement(nodeDescriptor);
252 protected boolean isAlwaysShowPlus(final NodeDescriptor descriptor) {
253 return false;
258 protected boolean isSmartExpand() {
259 return true;
262 public final boolean isDisposed() {
263 return getUi() == null || getUi().isReleaseRequested();
267 * @deprecated
268 * @param node
270 public final void updateSubtree(final DefaultMutableTreeNode node) {
271 getUi().updateSubtree(node, true);
274 public final boolean wasRootNodeInitialized() {
275 return getUi().wasRootNodeInitialized();
278 public final boolean isNodeBeingBuilt(final TreePath path) {
279 return getUi().isNodeBeingBuilt(path);
283 * @deprecated
284 * @param path
286 public final void buildNodeForPath(final Object[] path) {
287 getUi().buildNodeForPath(path);
291 * @deprecated
293 public final DefaultMutableTreeNode getNodeForPath(final Object[] path) {
294 return getUi().getNodeForPath(path);
297 protected Object findNodeByElement(final Object element) {
298 return getUi().findNodeByElement(element);
301 public static boolean isLoadingNode(final DefaultMutableTreeNode node) {
302 return AbstractTreeUi.isLoadingNode(node);
305 public boolean isChildrenResortingNeeded(NodeDescriptor descriptor) {
306 return true;
309 protected void runOnYeildingDone(Runnable onDone) {
310 if (myUi.isPassthroughMode()) {
311 onDone.run();
312 } else {
313 UIUtil.invokeLaterIfNeeded(onDone);
317 protected void yield(Runnable runnable) {
318 if (myUi.isPassthroughMode()) {
319 runnable.run();
320 } else {
321 SwingUtilities.invokeLater(runnable);
325 public boolean isToYieldUpdateFor(DefaultMutableTreeNode node) {
326 return true;
329 public boolean isToEnsureSelectionOnFocusGained() {
330 return true;
333 protected void runBackgroundLoading(final Runnable runnable) {
334 if (isDisposed()) return;
335 final Application app = ApplicationManager.getApplication();
336 if (app != null) {
337 app.runReadAction(new Runnable() {
338 public void run() {
339 runnable.run();
342 } else {
343 runnable.run();
347 protected ProgressIndicator getProgressIndicator() {
348 return getUi().getProgressIndicator();
351 protected void updateAfterLoadedInBackground(Runnable runnable) {
352 if (myUi.isPassthroughMode()) {
353 runnable.run();
354 } else {
355 UIUtil.invokeLaterIfNeeded(runnable);
359 public final ActionCallback getIntialized() {
360 return myUi.getInitialized();
363 public final ActionCallback getReady(Object requestor) {
364 return myUi.getReady(requestor);
367 protected void sortChildren(Comparator<TreeNode> nodeComparator, DefaultMutableTreeNode node, ArrayList<TreeNode> children) {
368 Collections.sort(children, nodeComparator);
371 public void setPassthroughMode(boolean passthrough) {
372 myUi.setPassthroughMode(passthrough);
375 public static class AbstractTreeNodeWrapper extends AbstractTreeNode<Object> {
376 public AbstractTreeNodeWrapper() {
377 super(null, null);
380 @NotNull
381 public Collection<AbstractTreeNode> getChildren() {
382 return Collections.emptyList();
385 public void update(PresentationData presentation) {
389 public final AbstractTreeUi getUi() {
390 return myUi;
393 public void dispose() {
394 if (isDisposed()) return;
396 myUi.requestRelease();
399 void releaseUi() {
400 myUi = null;
403 protected boolean updateNodeDescriptor(final NodeDescriptor descriptor) {
404 return getUi().doUpdateNodeDescriptor(descriptor);
407 public final DefaultTreeModel getTreeModel() {
408 return (DefaultTreeModel)getTree().getModel();
411 @NotNull
412 public final Set<Object> getSelectedElements() {
413 return getUi().getSelectedElements();
416 @NotNull
417 public final <T> Set<T> getSelectedElements(Class<T> elementClass) {
418 Set<T> result = new HashSet<T>();
419 for (Object o : getSelectedElements()) {
420 Object each = transformElement(o);
421 if (elementClass.isInstance(each)) {
422 //noinspection unchecked
423 result.add((T) each);
426 return result;
429 protected Object transformElement(Object object) {
430 return object;
433 public final void setCanYieldUpdate(boolean yield) {
434 getUi().setCanYield(yield);
437 @Nullable
438 public static AbstractTreeBuilder getBuilderFor(JTree tree) {
439 final WeakReference ref = (WeakReference)tree.getClientProperty(TREE_BUILDER);
440 return ref != null ? (AbstractTreeBuilder)ref.get() : null;
443 @Nullable
444 public final <T> Object accept(Class nodeClass, TreeVisitor<T> visitor) {
445 return accept(nodeClass, getTreeStructure().getRootElement(), visitor);
448 @Nullable
449 private <T> Object accept(Class nodeClass, Object element, TreeVisitor<T> visitor) {
450 if (element == null) return null;
452 if (nodeClass.isAssignableFrom(element.getClass())) {
453 if (visitor.visit((T)element)) return element;
456 final Object[] children = getTreeStructure().getChildElements(element);
457 for (Object each : children) {
458 final Object childObject = accept(nodeClass, each, visitor);
459 if (childObject != null) return childObject;
462 return null;
465 public <T> boolean select(Class nodeClass, TreeVisitor<T> visitor, @Nullable Runnable onDone, boolean addToSelection) {
466 final Object element = accept(nodeClass, visitor);
467 if (element != null) {
468 select(element, onDone, addToSelection);
469 return true;
472 return false;
475 public void scrollSelectionToVisible(@Nullable Runnable onDone, boolean shouldBeCentered) {
476 myUi.scrollSelectionToVisible(onDone, shouldBeCentered);
479 protected boolean isUnitTestingMode() {
480 Application app = ApplicationManager.getApplication();
481 return app != null && app.isUnitTestMode();