This commit is contained in:
Alexey Kudravtsev
2018-09-19 13:29:01 +03:00
parent e11b0fbc34
commit 83d30bde63
12 changed files with 60 additions and 50 deletions
@@ -22,8 +22,7 @@ import java.awt.*;
import java.util.Collection;
import java.util.Map;
public abstract class AbstractTreeNode<T>
extends PresentableNodeDescriptor<AbstractTreeNode<T>>
public abstract class AbstractTreeNode<T> extends PresentableNodeDescriptor<AbstractTreeNode<T>>
implements NavigationItem, Queryable.Contributor, LeafState.Supplier {
private static final TextAttributesKey FILESTATUS_ERRORS = TextAttributesKey.createTextAttributesKey("FILESTATUS_ERRORS");
@@ -32,10 +31,10 @@ public abstract class AbstractTreeNode<T>
private Object myValue;
private boolean myNullValueSet;
private final boolean myNodeWrapper;
static final Object TREE_WRAPPER_VALUE = new Object();
protected AbstractTreeNode(Project project, T value) {
protected AbstractTreeNode(Project project, @NotNull T value) {
super(project, null);
// assume that null value used for AbstractTreeNodeWrapper only
myNodeWrapper = setInternalValue(value);
}
@@ -153,7 +152,7 @@ public abstract class AbstractTreeNode<T>
public final void setValue(T value) {
boolean debug = !myNodeWrapper && LOG.isDebugEnabled();
int hash = !debug ? 0 : hashCode();
myNullValueSet = setInternalValue(value);
myNullValueSet = value == null || setInternalValue(value);
if (debug && hash != hashCode()) {
LOG.warn("hash code changed: " + myValue);
}
@@ -165,8 +164,8 @@ public abstract class AbstractTreeNode<T>
* @param value a new value to set
* @return {@code true} if the specified value is {@code null} and the anchor is not changed
*/
private boolean setInternalValue(T value) {
if (value == null) return true;
private boolean setInternalValue(@NotNull T value) {
if (value == TREE_WRAPPER_VALUE) return true;
myValue = TreeAnchorizer.getService().createAnchor(value);
return false;
}
@@ -40,6 +40,7 @@ public interface ActionToolbar {
/**
* @return component which represents the tool bar on UI
*/
@NotNull
JComponent getComponent();
/**
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.keymap.impl.IdeMouseEventDispatcher;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
@@ -72,8 +73,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static com.intellij.openapi.keymap.impl.IdeMouseEventDispatcher.requestFocusInNonFocusedWindow;
public class StructureViewComponent extends SimpleToolWindowPanel implements TreeActionsOwner, DataProvider, StructureView.Scrollable {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.structureView.newStructureView.StructureViewComponent");
@@ -130,6 +129,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
getRootElement() == element;
}
@NotNull
@Override
protected TreeElementWrapper createTree() {
return new MyNodeWrapper(myProject, myModel.getRoot(), myModel);
@@ -157,12 +157,9 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
final ModelListener modelListener = () -> queueUpdate();
myTreeModelWrapper.addModelListener(modelListener);
Disposer.register(this, new Disposable() {
@Override
public void dispose() {
storeState();
myTreeModelWrapper.removeModelListener(modelListener);
}
Disposer.register(this, () -> {
storeState();
myTreeModelWrapper.removeModelListener(modelListener);
});
setContent(ScrollPaneFactory.createScrollPane(myTree));
@@ -197,6 +194,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
setToolbar(createToolbar());
}
@NotNull
private JComponent createToolbar() {
return ActionManager.getInstance().createActionToolbar(ActionPlaces.STRUCTURE_VIEW_TOOLBAR, createActionGroup(), true).getComponent();
}
@@ -324,6 +322,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
}
}
@NotNull
protected ActionGroup createActionGroup() {
DefaultActionGroup result = new DefaultActionGroup();
Sorter[] sorters = myTreeModel.getSorters();
@@ -361,7 +360,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
return result;
}
protected void addGroupByActions(DefaultActionGroup result) {
protected void addGroupByActions(@NotNull DefaultActionGroup result) {
Grouper[] groupers = myTreeModel.getGroupers();
for (Grouper grouper : groupers) {
result.add(new TreeActionWrapper(grouper, this));
@@ -535,7 +534,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
private final class MyAutoScrollToSourceHandler extends AutoScrollToSourceHandler {
private boolean myShouldAutoScroll = true;
public void setShouldAutoScroll(boolean shouldAutoScroll) {
void setShouldAutoScroll(boolean shouldAutoScroll) {
myShouldAutoScroll = shouldAutoScroll;
}
@@ -585,12 +584,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
}
private void addEditorCaretListener() {
myFileEditorPositionListener = new FileEditorPositionListener() {
@Override
public void onCurrentElementChanged() {
scrollToSelectedElement();
}
};
myFileEditorPositionListener = () -> scrollToSelectedElement();
myTreeModel.addEditorPositionListener(myFileEditorPositionListener);
if (isAutoScrollEnabled()) {
@@ -715,7 +709,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
private long childrenStamp = -1;
private int modificationCountForChildren = ourSettingsModificationCount.get();
MyNodeWrapper(Project project, TreeElement value, TreeModel treeModel) {
MyNodeWrapper(Project project, @NotNull TreeElement value, @NotNull TreeModel treeModel) {
super(project, value, treeModel);
}
@@ -788,21 +782,24 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
return null;
}
@NotNull
@Override
protected TreeElementWrapper createChildNode(@NotNull TreeElement child) {
return new MyNodeWrapper(myProject, child, myTreeModel);
}
@NotNull
@Override
protected GroupWrapper createGroupWrapper(Project project, @NotNull Group group, final TreeModel treeModel) {
protected GroupWrapper createGroupWrapper(Project project, @NotNull Group group, @NotNull final TreeModel treeModel) {
return new MyGroupWrapper(project, group, treeModel);
}
@Override
public boolean equals(Object o) {
if (o instanceof MyNodeWrapper) {
return Comparing.equal(unwrapElement(getValue()), unwrapElement(((MyNodeWrapper)o).getValue()));
}
else if (o instanceof StructureViewTreeElement) {
if (o instanceof StructureViewTreeElement) {
return Comparing.equal(unwrapElement(getValue()), ((StructureViewTreeElement)o).getValue());
}
return false;
@@ -815,6 +812,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
return psi == null || psi.isValid();
}
@Override
public int hashCode() {
final Object o = unwrapElement(getValue());
@@ -823,18 +821,20 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
}
private static class MyGroupWrapper extends GroupWrapper {
MyGroupWrapper(Project project, Group group, TreeModel treeModel) {
MyGroupWrapper(Project project, @NotNull Group group, @NotNull TreeModel treeModel) {
super(project, group, treeModel);
}
@NotNull
@Override
protected TreeElementWrapper createChildNode(@NotNull TreeElement child) {
return new MyNodeWrapper(getProject(), child, myTreeModel);
}
@NotNull
@Override
protected GroupWrapper createGroupWrapper(Project project, @NotNull Group group, TreeModel treeModel) {
protected GroupWrapper createGroupWrapper(Project project, @NotNull Group group, @NotNull TreeModel treeModel) {
return new MyGroupWrapper(project, group, treeModel);
}
@@ -857,7 +857,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
@Override
public void processMouseEvent(MouseEvent event) {
requestFocusInNonFocusedWindow(event);
IdeMouseEventDispatcher.requestFocusInNonFocusedWindow(event);
super.processMouseEvent(event);
}
}
@@ -940,7 +940,8 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
}
// for FileStructurePopup only
public static TreeElementWrapper createWrapper(Project project, TreeElement value, TreeModel treeModel) {
@NotNull
public static TreeElementWrapper createWrapper(@NotNull Project project, @NotNull TreeElement value, TreeModel treeModel) {
return new MyNodeWrapper(project, value, treeModel);
}
@@ -161,6 +161,7 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
return getRootElement() == element;
}
@NotNull
@Override
protected TreeElementWrapper createTree() {
return StructureViewComponent.createWrapper(myProject, myModel.getRoot(), myModel);
@@ -455,7 +455,7 @@ public class AbstractTreeBuilder implements Disposable {
private static class AbstractTreeNodeWrapper extends AbstractTreeNode<Object> {
AbstractTreeNodeWrapper() {
super(null, null);
super(null, TREE_WRAPPER_VALUE);
}
@Override
@@ -37,11 +37,12 @@ public class StructureViewElementWrapper<V extends PsiElement> implements Struct
private final StructureViewTreeElement myTreeElement;
private final PsiFile myMainFile;
public StructureViewElementWrapper(@NotNull StructureViewTreeElement treeElement, @NotNull PsiFile mainFile) {
StructureViewElementWrapper(@NotNull StructureViewTreeElement treeElement, @NotNull PsiFile mainFile) {
myTreeElement = treeElement;
myMainFile = mainFile;
}
@NotNull
public StructureViewTreeElement getWrappedElement() {
return myTreeElement;
}
@@ -31,10 +31,11 @@ import java.util.*;
public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<Value> {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.smartTree.CachingChildrenTreeNode");
private List<CachingChildrenTreeNode> myChildren;
private List<CachingChildrenTreeNode> myOldChildren = null;
private List<CachingChildrenTreeNode> myOldChildren;
@NotNull
protected final TreeModel myTreeModel;
public CachingChildrenTreeNode(Project project, Value value, TreeModel treeModel) {
CachingChildrenTreeNode(Project project, @NotNull Value value, @NotNull TreeModel treeModel) {
super(project,
value instanceof StructureViewElementWrapper ? (Value) ((StructureViewElementWrapper) value).getWrappedElement() : value);
myTreeModel = treeModel;
@@ -59,7 +60,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
}
protected void addSubElement(CachingChildrenTreeNode node) {
void addSubElement(@NotNull CachingChildrenTreeNode node) {
JBIterable<AbstractTreeNode> parents = JBIterable.generate(this, o -> o.getParent());
if (parents.map(o -> o.getValue()).contains(node.getValue())) {
return;
@@ -69,7 +70,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
node.setParent(this);
}
protected void setChildren(Collection<? extends AbstractTreeNode> children) {
protected void setChildren(@NotNull Collection<? extends AbstractTreeNode> children) {
clearChildren();
for (AbstractTreeNode node : children) {
myChildren.add((CachingChildrenTreeNode)node);
@@ -77,10 +78,10 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
}
private static class CompositeComparator implements java.util.Comparator<CachingChildrenTreeNode> {
private static class CompositeComparator implements Comparator<CachingChildrenTreeNode> {
private final Sorter[] mySorters;
CompositeComparator(final Sorter[] sorters) {
CompositeComparator(@NotNull Sorter[] sorters) {
mySorters = sorters;
}
@@ -96,7 +97,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
}
protected void sortChildren(Sorter[] sorters) {
protected void sortChildren(@NotNull Sorter[] sorters) {
if (myChildren == null) return;
Collections.sort(myChildren, new CompositeComparator(sorters));
@@ -122,7 +123,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
setChildren(children);
}
protected void groupChildren(@NotNull Grouper[] groupers) {
void groupChildren(@NotNull Grouper[] groupers) {
for (Grouper grouper : groupers) {
groupElements(grouper);
}
@@ -134,7 +135,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
}
private void groupElements(Grouper grouper) {
private void groupElements(@NotNull Grouper grouper) {
ArrayList<AbstractTreeNode<TreeElement>> ungrouped = new ArrayList<>();
Collection<AbstractTreeNode> children = getChildren();
for (AbstractTreeNode child : children) {
@@ -185,11 +186,13 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
}
@NotNull
protected TreeElementWrapper createChildNode(@NotNull TreeElement child) {
return new TreeElementWrapper(getProject(), child, myTreeModel);
}
private static Map<TreeElement, AbstractTreeNode> collectValues(List<? extends AbstractTreeNode<TreeElement>> ungrouped) {
@NotNull
private static Map<TreeElement, AbstractTreeNode> collectValues(@NotNull List<? extends AbstractTreeNode<TreeElement>> ungrouped) {
Map<TreeElement, AbstractTreeNode> objects = new LinkedHashMap<>();
for (final AbstractTreeNode<TreeElement> node : ungrouped) {
objects.put(node.getValue(), node);
@@ -197,6 +200,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
return objects;
}
@NotNull
private Map<Group, GroupWrapper> createGroupNodes(@NotNull Collection<? extends Group> groups) {
Map<Group, GroupWrapper> result = new THashMap<>();
for (Group group : groups) {
@@ -205,7 +209,8 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
return result;
}
protected GroupWrapper createGroupWrapper(final Project project, @NotNull Group group, final TreeModel treeModel) {
@NotNull
protected GroupWrapper createGroupWrapper(final Project project, @NotNull Group group, @NotNull TreeModel treeModel) {
return new GroupWrapper(project, group, treeModel);
}
@@ -218,7 +223,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
protected void synchronizeChildren() {
void synchronizeChildren() {
List<CachingChildrenTreeNode> children = myChildren;
if (myOldChildren != null && children != null) {
HashMap<Object, CachingChildrenTreeNode> oldValuesToChildrenMap = new HashMap<>();
@@ -275,7 +280,7 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
}
public void rebuildChildren() {
void rebuildChildren() {
if (myChildren != null) {
myOldChildren = myChildren;
for (final CachingChildrenTreeNode node : myChildren) {
@@ -25,7 +25,7 @@ import java.util.Collection;
public class GroupWrapper extends CachingChildrenTreeNode<Group> {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.smartTree.GroupWrapper");
public GroupWrapper(Project project, Group value, TreeModel treeModel) {
public GroupWrapper(Project project, @NotNull Group value, @NotNull TreeModel treeModel) {
super(project, value, treeModel);
clearChildren();
}
@@ -25,7 +25,7 @@ import com.intellij.psi.PsiDocumentManager;
import org.jetbrains.annotations.NotNull;
public class SmartTreeStructure extends AbstractTreeStructure {
@NotNull
protected final TreeModel myModel;
protected final Project myProject;
private TreeElementWrapper myRootElementWrapper;
@@ -77,6 +77,7 @@ public class SmartTreeStructure extends AbstractTreeStructure {
return myRootElementWrapper;
}
@NotNull
protected TreeElementWrapper createTree() {
return new TreeElementWrapper(myProject, myModel.getRoot(), myModel);
}
@@ -28,7 +28,7 @@ import java.util.Collection;
public class TreeElementWrapper extends CachingChildrenTreeNode<TreeElement> {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.treeView.smartTree.TreeElementWrapper");
public TreeElementWrapper(Project project, TreeElement value, TreeModel treeModel) {
public TreeElementWrapper(Project project, @NotNull TreeElement value, @NotNull TreeModel treeModel) {
super(project, value, treeModel);
}
@@ -29,7 +29,7 @@ public class PropertiesGroupingStructureViewComponent extends StructureViewCompo
}
@Override
protected void addGroupByActions(DefaultActionGroup result) {
protected void addGroupByActions(@NotNull DefaultActionGroup result) {
super.addGroupByActions(result);
result.add(new ChangeGroupSeparatorAction());
if (getTreeModel() instanceof ResourceBundleStructureViewModel) {
@@ -64,6 +64,7 @@ public class ResourceBundleStructureViewComponent extends PropertiesGroupingStru
getTree().setCellRenderer(new ResourceBundleEditorRenderer());
}
@NotNull
@Override
protected ActionGroup createActionGroup() {
final DefaultActionGroup result = (DefaultActionGroup) super.createActionGroup();
@@ -72,7 +73,7 @@ public class ResourceBundleStructureViewComponent extends PropertiesGroupingStru
}
@Override
protected void addGroupByActions(final DefaultActionGroup result) {
protected void addGroupByActions(@NotNull final DefaultActionGroup result) {
super.addGroupByActions(result);
result.add(new NewPropertyAction(true), Constraints.FIRST);
}