}
public final void select(final Object element, @Nullable final Runnable onDone) {
- getUi().userSelect(new Object[] {element}, onDone, false, true);
+ getUi().userSelect(new Object[] {element}, new UserRunnable(onDone), false, true);
}
public final void select(final Object element, @Nullable final Runnable onDone, boolean addToSelection) {
- getUi().userSelect(new Object[] {element}, onDone, addToSelection, true);
+ getUi().userSelect(new Object[] {element}, new UserRunnable(onDone), addToSelection, true);
}
public final void select(final Object[] elements, @Nullable final Runnable onDone) {
- getUi().userSelect(elements, onDone, false, true);
+ getUi().userSelect(elements, new UserRunnable(onDone), false, true);
}
public final void select(final Object[] elements, @Nullable final Runnable onDone, boolean addToSelection) {
- getUi().userSelect(elements, onDone, addToSelection, true);
+ getUi().userSelect(elements, new UserRunnable(onDone), addToSelection, true);
}
public final void expand(Object element, @Nullable Runnable onDone) {
- getUi().expand(element, onDone);
+ getUi().expand(element, new UserRunnable(onDone));
}
public final void expand(Object[] element, @Nullable Runnable onDone) {
- getUi().expand(element, onDone);
+ getUi().expand(element, new UserRunnable(onDone));
}
public final void collapseChildren(Object element, @Nullable Runnable onDone) {
- getUi().collapseChildren(element, onDone);
+ getUi().collapseChildren(element, new UserRunnable(onDone));
}
return builder != null && builder.getUi() != null ? builder.getUi().isToPaintSelection() : true;
}
+ class UserRunnable implements Runnable {
+
+ private Runnable myRunnable;
+
+ public UserRunnable(Runnable runnable) {
+ myRunnable = runnable;
+ }
+
+ @Override
+ public void run() {
+ if (myRunnable != null) {
+ AbstractTreeUi ui = getUi();
+ if (ui != null) {
+ ui.executeUserRunnable(myRunnable);
+ } else {
+ myRunnable.run();
+ }
+ }
+ }
+ }
+
}
private Set<Object> myRevalidatedObjects = new HashSet<Object>();
+ private Set<Runnable> myUserRunnables = new HashSet<Runnable>();
+
private Alarm myMaybeReady = new Alarm();
private Runnable myMaybeReadyRunnable = new Runnable() {
@Override
final NodeDescriptor descriptor = getDescriptorFrom(node);
if (descriptor == null) {
+ removeFromUnbuilt(node);
removeLoading(node, true);
return;
}
if (desc == null) return false;
if (getTreeStructure().isAlwaysLeaf(element)) {
+ removeFromUnbuilt(node);
removeLoading(node, true);
if (node.getChildCount() > 0) {
final boolean canSmartExpand = canSmartExpand(node, toSmartExpand);
+ removeFromUnbuilt(node);
+
processExistingNodes(node, elementToIndexMap, pass, canSmartExpand(node, toSmartExpand), forceUpdate, wasExpanded, preloadedChildren)
.doWhenDone(new Runnable() {
public void run() {
public void run(ArrayList<TreeNode> nodesToInsert) {
insertNodesInto(nodesToInsert, node);
updateNodesToInsert(nodesToInsert, pass, canSmartExpand, isChildNodeForceUpdate(node, forceUpdate, expanded));
- removeLoading(node, true);
+ removeLoading(node, false);
removeFromUpdating(node);
if (node.getChildCount() > 0) {
boolean processed;
if (children.getElements().size() == 0) {
+ removeFromUnbuilt(node);
removeLoading(node, true);
processed = true;
}
}
}
else {
+ removeFromUnbuilt(node);
removeLoading(node, true);
}
}
return myReleaseRequested;
}
+ public void executeUserRunnable(Runnable runnable) {
+ try {
+ myUserRunnables.add(runnable);
+ runnable.run();
+ }
+ finally {
+ myUserRunnables.remove(runnable);
+ }
+ }
+
static class ElementNode extends DefaultMutableTreeNode {
Set<Object> myElements = new HashSet<Object>();
myTreeModel.insertNodeInto(loadingNode, node, node.getChildCount());
}
+ removeFromUnbuilt(node);
+
final Ref<LoadedChildren> children = new Ref<LoadedChildren>();
final Ref<Object> elementFromDescriptor = new Ref<Object>();
public void run() {
if (isReleased()) return;
- removeLoading(node, true);
+ removeLoading(node, false);
removeFromLoadedInBackground(elementFromDescriptor.get());
removeFromLoadedInBackground(oldElementFromDescriptor);
Object element = elementFromDescriptor.get();
if (element != null) {
- removeLoading(node, true);
+ removeLoading(node, false);
nodeToProcessActions[0] = node;
}
}
return isExpanded || myTree.isExpanded(getPathFor(node));
}
- private void removeLoading(DefaultMutableTreeNode parent, boolean removeFromUnbuilt) {
+ private void removeLoading(DefaultMutableTreeNode parent, boolean forced) {
+ if (!forced && myUnbuiltNodes.contains(parent) && !myCancelledBuild.containsKey(parent)) {
+ return;
+ }
+
for (int i = 0; i < parent.getChildCount(); i++) {
TreeNode child = parent.getChildAt(i);
if (removeIfLoading(child)) {
}
}
- if (removeFromUnbuilt) {
- removeFromUnbuilt(parent);
- }
-
if (parent == getRootNode() && !myTree.isRootVisible() && parent.getChildCount() == 0) {
insertLoadingNode(parent, false);
}
}
private boolean isInnerChange() {
- return myUpdaterState != null && myUpdaterState.isProcessingNow();
+ return (myUpdaterState != null && myUpdaterState.isProcessingNow()) && myUserRunnables.size() == 0;
}
protected boolean doUpdateNodeDescriptor(final NodeDescriptor descriptor) {
public boolean addSubtreeToUpdate(final DefaultMutableTreeNode root, final Runnable runAfterUpdate) {
Object element = getElementFor(root);
if (getTreeStructure().isAlwaysLeaf(element)) {
+ removeFromUnbuilt(root);
removeLoading(root, true);
if (runAfterUpdate != null) {
if (isLoadingParent(node)) return (DefaultMutableTreeNode)node;
- final boolean childrenAreNoLoadedYet = myUnbuiltNodes.contains(node);
+ DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)node;
+
+ final boolean childrenAreNoLoadedYet = myUnbuiltNodes.contains(treeNode) || isUpdatingNow(treeNode);
if (childrenAreNoLoadedYet) {
if (node instanceof DefaultMutableTreeNode) {
final TreePath nodePath = new TreePath(((DefaultMutableTreeNode)node).getPath());