diff --git a/src/main/java/com/redhat/devtools/intellij/common/tree/MutableModelSynchronizer.java b/src/main/java/com/redhat/devtools/intellij/common/tree/MutableModelSynchronizer.java index 61980be..d5b209e 100644 --- a/src/main/java/com/redhat/devtools/intellij/common/tree/MutableModelSynchronizer.java +++ b/src/main/java/com/redhat/devtools/intellij/common/tree/MutableModelSynchronizer.java @@ -12,9 +12,13 @@ import com.intellij.ide.util.treeView.AbstractTreeStructure; import com.intellij.ide.util.treeView.NodeDescriptor; +import com.intellij.ide.util.treeView.PresentableNodeDescriptor; import com.intellij.ui.tree.StructureTreeModel; +import com.intellij.ui.tree.TreePathUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.util.Enumeration; import java.util.function.Supplier; @@ -55,21 +59,42 @@ private T getParentElement(T element) { } protected TreePath getTreePath(T element) { - TreePath path; + if (element == null) { + return null; + } + TreeNode node = getNode(element); + if (node != null) { + return new TreePath(node); + } else { + return new TreePath(treeModel.getRoot()); + } + } + + @Nullable + private TreeNode getNode(T element) { + TreeNode node; if (isRootNode(element)) { - path = new TreePath(treeModel.getRoot()); + node = treeModel.getRoot(); } else { - path = findTreePath(element, (DefaultMutableTreeNode)treeModel.getRoot()); + node = findTreeNode(element, (DefaultMutableTreeNode)treeModel.getRoot()); } - return path!=null?path:new TreePath(treeModel.getRoot()); + return node; } protected boolean isRootNode(T element) { - NodeDescriptor descriptor = (NodeDescriptor) ((DefaultMutableTreeNode)treeModel.getRoot()).getUserObject(); - return descriptor != null && descriptor.getElement() == element; + TreeNode root = treeModel.getRoot(); + if (!(root instanceof DefaultMutableTreeNode)) { + return false; + } + Object userObject = ((DefaultMutableTreeNode) root).getUserObject(); + if (!(userObject instanceof NodeDescriptor) ){ + return false; + } + NodeDescriptor descriptor = (NodeDescriptor) userObject; + return descriptor.getElement() == element; } - private TreePath findTreePath(T element, DefaultMutableTreeNode start) { + private TreeNode findTreeNode(T element, DefaultMutableTreeNode start) { if (element == null || start == null) { return null; @@ -81,34 +106,58 @@ private TreePath findTreePath(T element, DefaultMutableTreeNode start) { continue; } if (hasElement(element, (DefaultMutableTreeNode) child)) { - return new TreePath(((DefaultMutableTreeNode)child).getPath()); + return (DefaultMutableTreeNode) child; } - TreePath path = findTreePath(element, (DefaultMutableTreeNode) child); - if (path != null) { - return path; + TreeNode node = findTreeNode(element, (DefaultMutableTreeNode) child); + if (node != null) { + return node; } } return null; } private boolean hasElement(T element, DefaultMutableTreeNode node) { - NodeDescriptor descriptor = (NodeDescriptor) node.getUserObject(); + NodeDescriptor descriptor = (NodeDescriptor) node.getUserObject(); return descriptor != null && descriptor.getElement() == element; } @Override public void onAdded(T element) { - invalidatePath(() -> getTreePath(getParentElement(element))); + treeModel.getInvoker().invokeLater(() -> + invalidatePath(() -> getTreePath(getParentElement(element))) + ); } @Override public void onModified(T element) { - invalidatePath(() -> getTreePath(element)); + treeModel.getInvoker().invokeLater(() -> { + TreePath path = getTreePath(element); + if (path == null) { + return; + } + updateDescriptor(path); + invalidatePath(() -> path); + }); + } + + private void updateDescriptor(TreePath path) { + TreeNode node = TreePathUtil.toTreeNode(path); + if (!(node instanceof DefaultMutableTreeNode)) { + return; + } + Object userObject = ((DefaultMutableTreeNode) node).getUserObject(); + if (!(userObject instanceof PresentableNodeDescriptor)) { + return; + } + + ((PresentableNodeDescriptor) userObject).update(); } @Override public void onRemoved(T element) { - invalidatePath(() -> getTreePath(getParentElement(element))); + treeModel.getInvoker().invokeLater(() -> + invalidatePath(() -> getTreePath(getParentElement(element))) + ); } }