/*
* Copyright 2000-2007 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ui.treeStructure;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.AbstractTreeUpdater;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.util.Comparator;
/**
* @author peter
*/
public abstract class LazyTreeBuilder extends AbstractTreeBuilder {
private boolean myWaiting;
private boolean myUpdating;
private final AbstractTreeStructure myDelegateStructure;
public LazyTreeBuilder(final JTree tree,
final DefaultTreeModel treeModel,
final AbstractTreeStructure structure,
final Comparator<NodeDescriptor> comparator) {
super(tree, treeModel, null, comparator);
myDelegateStructure = structure;
myTreeStructure = new AbstractTreeStructure() {
public Object getRootElement() {
return structure.getRootElement();
}
public Object[] getChildElements(Object element) {
if (isWaiting()) return ArrayUtil.EMPTY_OBJECT_ARRAY;
return structure.getChildElements(element);
}
public Object getParentElement(Object element) {
return structure.getParentElement(element);
}
@NotNull
public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) {
return structure.createDescriptor(element, parentDescriptor);
}
public void commit() {
structure.commit();
}
public boolean isToBuildChildrenInBackground(Object element) {
return isWaiting();
}
public boolean hasSomethingToCommit() {
return structure.hasSomethingToCommit();
}
};
}
public final AbstractTreeStructure getDelegateStructure() {
return myDelegateStructure;
}
protected AbstractTreeUpdater createUpdater() {
return new AbstractTreeUpdater(this) {
public synchronized void performUpdate() {
setWaiting(false);
try {
setUpdating(true);
super.performUpdate();
}
finally {
setUpdating(false);
}
}
};
}
protected void expandNodeChildren(final DefaultMutableTreeNode node) {
if (isWaiting()) {
myUpdater.addSubtreeToUpdate(node);
updateSubtree(node);
}
else {
super.expandNodeChildren(node);
}
}
private boolean isWaiting() {
synchronized (myUpdater) {
return myWaiting;
}
}
protected void updateNode(DefaultMutableTreeNode node) {
if (isWaiting()) return;
super.updateNode(node);
}
public final void queueUpdate() {
queueUpdate(myRootNode);
}
public final void queueUpdate(DefaultMutableTreeNode node) {
setWaiting(true);
myUpdater.addSubtreeToUpdate(node);
}
public final boolean queueUpdateByElement(Object element) {
setWaiting(true);
return myUpdater.addSubtreeToUpdateByElement(element);
}
public final void setWaiting(final boolean b) {
synchronized (myUpdater) {
if (myUpdating) return;
myWaiting = b;
}
}
private void setUpdating(final boolean updating) {
synchronized (myUpdater) {
myUpdating = updating;
}
}
}