private static void drawSelection(JTree tree, Graphics g, final int width) {
   int y = 0;
   final int[] rows = tree.getSelectionRows();
   final int height = tree.getRowHeight();
   for (int row : rows) {
     final TreeCellRenderer renderer = tree.getCellRenderer();
     final Object value = tree.getPathForRow(row).getLastPathComponent();
     if (value == null) continue;
     final Component component =
         renderer.getTreeCellRendererComponent(tree, value, false, false, false, row, false);
     if (component.getFont() == null) {
       component.setFont(tree.getFont());
     }
     g.translate(0, y);
     component.setBounds(0, 0, width, height);
     boolean wasOpaque = false;
     if (component instanceof JComponent) {
       final JComponent j = (JComponent) component;
       if (j.isOpaque()) wasOpaque = true;
       j.setOpaque(false);
     }
     component.paint(g);
     if (wasOpaque) {
       ((JComponent) component).setOpaque(true);
     }
     y += height;
     g.translate(0, -y);
   }
 }
 @Nullable
 private TreePath getSelectedUniquePath() {
   JTree tree = getTree();
   if (tree == null) return null;
   TreePath[] paths = tree.getSelectionPaths();
   return paths == null || paths.length != 1 ? null : paths[0];
 }
 public void addSelectionPathTo(final Object element) {
   DefaultMutableTreeNode node = myAbstractTreeBuilder.getNodeForElement(element);
   if (node != null) {
     final JTree tree = getTree();
     final TreePath path = new TreePath(node.getPath());
     if (node == tree.getModel().getRoot() && !tree.isExpanded(path)) tree.expandPath(path);
     tree.addSelectionPath(path);
   }
 }
  private static void printImpl(
      JTree tree,
      Object root,
      Collection<String> strings,
      int level,
      boolean withSelection,
      @Nullable Condition<String> nodePrintCondition) {
    DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) root;

    final Object userObject = defaultMutableTreeNode.getUserObject();
    String nodeText;
    if (userObject != null) {
      nodeText = toString(userObject, null);
    } else {
      nodeText = "null";
    }

    if (nodePrintCondition != null && !nodePrintCondition.value(nodeText)) return;

    final StringBuilder buff = new StringBuilder();
    StringUtil.repeatSymbol(buff, ' ', level);

    final boolean expanded = tree.isExpanded(new TreePath(defaultMutableTreeNode.getPath()));
    if (!defaultMutableTreeNode.isLeaf()) {
      buff.append(expanded ? "-" : "+");
    }

    final boolean selected =
        tree.getSelectionModel().isPathSelected(new TreePath(defaultMutableTreeNode.getPath()));
    if (withSelection && selected) {
      buff.append("[");
    }

    buff.append(nodeText);

    if (withSelection && selected) {
      buff.append("]");
    }

    strings.add(buff.toString());

    int childCount = tree.getModel().getChildCount(root);
    if (expanded) {
      for (int i = 0; i < childCount; i++) {
        printImpl(
            tree,
            tree.getModel().getChild(root, i),
            strings,
            level + 1,
            withSelection,
            nodePrintCondition);
      }
    }
  }
  @Override
  public void selectUsages(@NotNull Usage[] usages) {
    List<TreePath> paths = new LinkedList<TreePath>();

    for (Usage usage : usages) {
      final UsageNode node = myUsageNodes.get(usage);

      if (node != NULL_NODE && node != null) {
        paths.add(new TreePath(node.getPath()));
      }
    }

    myTree.setSelectionPaths(paths.toArray(new TreePath[paths.size()]));
    if (!paths.isEmpty()) myTree.scrollPathToVisible(paths.get(0));
  }
 private void restoreUsageExpandState(final Collection<UsageState> states) {
   // always expand the last level group
   final DefaultMutableTreeNode root = (DefaultMutableTreeNode) myTree.getModel().getRoot();
   for (int i = root.getChildCount() - 1; i >= 0; i--) {
     final DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
     if (child instanceof GroupNode) {
       final TreePath treePath = new TreePath(child.getPath());
       myTree.expandPath(treePath);
     }
   }
   myTree.getSelectionModel().clearSelection();
   for (final UsageState usageState : states) {
     usageState.restore();
   }
 }
 private void updateImmediately() {
   if (myProject.isDisposed()) return;
   checkNodeValidity((DefaultMutableTreeNode) myTree.getModel().getRoot());
   if (myUsagePreviewPanel != null) {
     myUsagePreviewPanel.updateLayout(getSelectedUsageInfos());
   }
 }
  private void layoutPanel() {
    if (myUsagePreviewPanel != null) {
      Disposer.dispose(myUsagePreviewPanel);
    }
    removeAll();
    JScrollPane pane = ScrollPaneFactory.createScrollPane(myTree);

    if (isPreview()) {
      pane.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.RIGHT));

      boolean vertical =
          myToolWindow.getAnchor() == ToolWindowAnchor.LEFT
              || myToolWindow.getAnchor() == ToolWindowAnchor.RIGHT;
      Splitter splitter =
          new Splitter(
              vertical, UsageViewSettings.getInstance().PREVIEW_USAGES_SPLITTER_PROPORTIONS);
      splitter.setFirstComponent(pane);
      myUsagePreviewPanel = new UsagePreviewPanel(myProject, new UsageViewPresentation());
      myUsagePreviewPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT));

      Disposer.register(this, myUsagePreviewPanel);
      splitter.setSecondComponent(myUsagePreviewPanel);
      add(splitter, BorderLayout.CENTER);
    } else {
      pane.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT));
      add(pane, BorderLayout.CENTER);
    }

    add(createToolbar().getComponent(), BorderLayout.WEST);

    myTree.getParent().setBackground(UIManager.getColor("Tree.background"));

    revalidate();
  }
 public static Collection<String> printAsList(
     JTree tree, boolean withSelection, @Nullable Condition<String> nodePrintCondition) {
   Collection<String> strings = new ArrayList<String>();
   Object root = tree.getModel().getRoot();
   printImpl(tree, root, strings, 0, withSelection, nodePrintCondition);
   return strings;
 }
    public static Image createImage(final JTree tree) {
      final TreeSelectionModel model = tree.getSelectionModel();
      final TreePath[] paths = model.getSelectionPaths();

      int count = 0;
      final List<ChangesBrowserNode> nodes = new ArrayList<ChangesBrowserNode>();
      for (final TreePath path : paths) {
        final ChangesBrowserNode node = (ChangesBrowserNode) path.getLastPathComponent();
        if (!node.isLeaf()) {
          nodes.add(node);
          count += node.getCount();
        }
      }

      for (TreePath path : paths) {
        final ChangesBrowserNode element = (ChangesBrowserNode) path.getLastPathComponent();
        boolean child = false;
        for (final ChangesBrowserNode node : nodes) {
          if (node.isNodeChild(element)) {
            child = true;
            break;
          }
        }

        if (!child) {
          if (element.isLeaf()) count++;
        } else if (!element.isLeaf()) {
          count -= element.getCount();
        }
      }

      final JLabel label = new JLabel(VcsBundle.message("changes.view.dnd.label", count));
      label.setOpaque(true);
      label.setForeground(tree.getForeground());
      label.setBackground(tree.getBackground());
      label.setFont(tree.getFont());
      label.setSize(label.getPreferredSize());
      final BufferedImage image =
          new BufferedImage(label.getWidth(), label.getHeight(), BufferedImage.TYPE_INT_ARGB);

      Graphics2D g2 = (Graphics2D) image.getGraphics();
      g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f));
      label.paint(g2);
      g2.dispose();

      return image;
    }
  public SlicePanel(
      @NotNull final Project project,
      boolean dataFlowToThis,
      @NotNull SliceNode rootNode,
      boolean splitByLeafExpressions,
      @NotNull final ToolWindow toolWindow) {
    super(new BorderLayout());
    myToolWindow = toolWindow;
    final ToolWindowManagerListener listener =
        new ToolWindowManagerListener() {
          ToolWindowAnchor myAnchor = toolWindow.getAnchor();

          @Override
          public void toolWindowRegistered(@NotNull String id) {}

          @Override
          public void stateChanged() {
            if (!project.isOpen()) return;
            if (toolWindow.getAnchor() != myAnchor) {
              myAnchor = myToolWindow.getAnchor();
              layoutPanel();
            }
          }
        };
    ToolWindowManagerEx.getInstanceEx(project).addToolWindowManagerListener(listener, this);

    ApplicationManager.getApplication().assertIsDispatchThread();
    myProject = project;
    myTree = createTree();

    myBuilder =
        new SliceTreeBuilder(myTree, project, dataFlowToThis, rootNode, splitByLeafExpressions);
    myBuilder.setCanYieldUpdate(!ApplicationManager.getApplication().isUnitTestMode());

    Disposer.register(this, myBuilder);

    myBuilder.addSubtreeToUpdate(
        (DefaultMutableTreeNode) myTree.getModel().getRoot(),
        new Runnable() {
          @Override
          public void run() {
            if (isDisposed || myBuilder.isDisposed() || myProject.isDisposed()) return;
            final SliceNode rootNode = myBuilder.getRootSliceNode();
            myBuilder.expand(
                rootNode,
                new Runnable() {
                  @Override
                  public void run() {
                    if (isDisposed || myBuilder.isDisposed() || myProject.isDisposed()) return;
                    myBuilder.select(
                        rootNode.myCachedChildren.get(0)); // first there is ony one child
                  }
                });
            treeSelectionChanged();
          }
        });

    layoutPanel();
  }
  protected JTree createTree() {
    myFileSystemTree = new FileSystemTreeImpl(myProject, myChooserDescriptor);
    Disposer.register(myDisposable, myFileSystemTree);

    myFileSystemTree.addOkAction(
        new Runnable() {
          public void run() {
            doOKAction();
          }
        });
    JTree tree = myFileSystemTree.getTree();
    tree.setCellRenderer(new NodeRenderer());
    tree.getSelectionModel().addTreeSelectionListener(new FileTreeSelectionListener());
    tree.addTreeExpansionListener(new FileTreeExpansionListener());
    setOKActionEnabled(false);

    myFileSystemTree.addListener(
        new FileSystemTree.Listener() {
          public void selectionChanged(final List<VirtualFile> selection) {
            updatePathFromTree(selection, false);
          }
        },
        myDisposable);

    new FileDrop(
        tree,
        new FileDrop.Target() {
          public FileChooserDescriptor getDescriptor() {
            return myChooserDescriptor;
          }

          public boolean isHiddenShown() {
            return myFileSystemTree.areHiddensShown();
          }

          public void dropFiles(final List<VirtualFile> files) {
            if (!myChooserDescriptor.isChooseMultiple() && files.size() > 0) {
              selectInTree(new VirtualFile[] {files.get(0)}, true);
            } else {
              selectInTree(VfsUtilCore.toVirtualFileArray(files), true);
            }
          }
        });

    return tree;
  }
  public final void changeView(@NotNull final String typeName) {
    myCurrentViewType = typeName;

    final PsiElement element = mySmartPsiElementPointer.getElement();
    if (element == null || !isApplicableElement(element)) {
      return;
    }

    if (myContent != null) {
      final String displayName = getContentDisplayName(typeName, element);
      if (displayName != null) {
        myContent.setDisplayName(displayName);
      }
    }

    myCardLayout.show(myTreePanel, typeName);

    if (!myBuilders.containsKey(typeName)) {
      try {
        setWaitCursor();
        // create builder
        final JTree tree = myType2TreeMap.get(typeName);
        final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode(""));
        tree.setModel(model);

        final HierarchyTreeStructure structure = createHierarchyTreeStructure(typeName, element);
        if (structure == null) {
          return;
        }
        final Comparator<NodeDescriptor> comparator = getComparator();
        final HierarchyTreeBuilder builder =
            new HierarchyTreeBuilder(myProject, tree, model, structure, comparator);

        myBuilders.put(typeName, builder);
        Disposer.register(this, builder);
        Disposer.register(builder, () -> myBuilders.remove(typeName));

        final HierarchyNodeDescriptor descriptor = structure.getBaseDescriptor();
        builder.select(descriptor, () -> builder.expand(descriptor, null));
      } finally {
        restoreCursor();
      }
    }

    getCurrentTree().requestFocus();
  }
  @Nullable
  private Node getSelectedNode() {
    TreePath leadSelectionPath = myTree.getLeadSelectionPath();
    if (leadSelectionPath == null) return null;

    DefaultMutableTreeNode node = (DefaultMutableTreeNode) leadSelectionPath.getLastPathComponent();
    return node instanceof Node ? (Node) node : null;
  }
 private void captureUsagesExpandState(TreePath pathFrom, final Collection<UsageState> states) {
   if (!myTree.isExpanded(pathFrom)) {
     return;
   }
   final DefaultMutableTreeNode node = (DefaultMutableTreeNode) pathFrom.getLastPathComponent();
   final int childCount = node.getChildCount();
   for (int idx = 0; idx < childCount; idx++) {
     final TreeNode child = node.getChildAt(idx);
     if (child instanceof UsageNode) {
       final Usage usage = ((UsageNode) child).getUsage();
       states.add(
           new UsageState(
               usage,
               myTree.getSelectionModel().isPathSelected(pathFrom.pathByAddingChild(child))));
     } else {
       captureUsagesExpandState(pathFrom.pathByAddingChild(child), states);
     }
   }
 }
 @Nullable
 private DefaultMutableTreeNode getNodeForPath(String path) {
   Enumeration enumeration =
       ((DefaultMutableTreeNode) myTree.getModel().getRoot()).preorderEnumeration();
   while (enumeration.hasMoreElements()) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
     if (Comparing.equal(getPath(node), path)) {
       return node;
     }
   }
   return null;
 }
 private ArrayList<DefaultMutableTreeNode> getNodesByPaths(ArrayList<String> paths) {
   final ArrayList<DefaultMutableTreeNode> result = new ArrayList<DefaultMutableTreeNode>();
   Enumeration enumeration =
       ((DefaultMutableTreeNode) myTree.getModel().getRoot()).preorderEnumeration();
   while (enumeration.hasMoreElements()) {
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
     final String path = getPath(node);
     if (paths.contains(path)) {
       result.add(node);
     }
   }
   return result;
 }
 @Nullable
 private List<UsageInfo> getSelectedUsageInfos() {
   TreePath[] paths = myTree.getSelectionPaths();
   if (paths == null) return null;
   final ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
   for (TreePath path : paths) {
     SliceNode sliceNode = fromPath(path);
     if (sliceNode != null) {
       result.add(sliceNode.getValue().getUsageInfo());
     }
   }
   if (result.isEmpty()) return null;
   return result;
 }
Beispiel #19
0
    @Override
    public void update(AnActionEvent e) {
      Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
      e.getPresentation().setEnabled(false);
      if (focusOwner instanceof JComponent
          && SpeedSearchBase.hasActiveSpeedSearch((JComponent) focusOwner)) {
        return;
      }

      if (StackingPopupDispatcher.getInstance().isPopupFocused()) return;

      if (focusOwner instanceof JTree) {
        JTree tree = (JTree) focusOwner;
        if (!tree.isEditing()) {
          e.getPresentation().setEnabled(true);
        }
      } else if (focusOwner instanceof JTable) {
        JTable table = (JTable) focusOwner;
        if (!table.isEditing()) {
          e.getPresentation().setEnabled(true);
        }
      }
    }
  private void initTree() {
    myTree.setRootVisible(false);
    myTree.setShowsRootHandles(true);
    SmartExpander.installOn(myTree);
    TreeUtil.installActions(myTree);
    EditSourceOnDoubleClickHandler.install(myTree);
    myTree.addKeyListener(
        new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent e) {
            if (KeyEvent.VK_ENTER == e.getKeyCode()) {
              TreePath leadSelectionPath = myTree.getLeadSelectionPath();
              if (leadSelectionPath == null) return;

              DefaultMutableTreeNode node =
                  (DefaultMutableTreeNode) leadSelectionPath.getLastPathComponent();
              if (node instanceof UsageNode) {
                final Usage usage = ((UsageNode) node).getUsage();
                usage.navigate(false);
                usage.highlightInEditor();
              } else if (node.isLeaf()) {
                Navigatable navigatable = getNavigatableForNode(node);
                if (navigatable != null && navigatable.canNavigate()) {
                  navigatable.navigate(false);
                }
              }
            }
          }
        });

    TreeUtil.selectFirstNode(myTree);
    PopupHandler.installPopupHandler(
        myTree, IdeActions.GROUP_USAGE_VIEW_POPUP, ActionPlaces.USAGE_VIEW_POPUP);
    // TODO: install speed search. Not in openapi though. It makes sense to create a common
    // TreeEnchancer service.
  }
  @Nullable
  private Node[] getSelectedNodes() {
    TreePath[] leadSelectionPath = myTree.getSelectionPaths();
    if (leadSelectionPath == null || leadSelectionPath.length == 0) return null;

    final List<Node> result = new ArrayList<Node>();
    for (TreePath comp : leadSelectionPath) {
      final Object lastPathComponent = comp.getLastPathComponent();
      if (lastPathComponent instanceof Node) {
        final Node node = (Node) lastPathComponent;
        result.add(node);
      }
    }
    return result.isEmpty() ? null : result.toArray(new Node[result.size()]);
  }
  @Override
  @Nullable
  public Set<Usage> getSelectedUsages() {
    TreePath[] selectionPaths = myTree.getSelectionPaths();
    if (selectionPaths == null) {
      return null;
    }

    Set<Usage> usages = new THashSet<Usage>();
    for (TreePath selectionPath : selectionPaths) {
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
      collectUsages(node, usages);
    }

    return usages;
  }
  @Nullable
  private UsageTarget[] getSelectedUsageTargets() {
    TreePath[] selectionPaths = myTree.getSelectionPaths();
    if (selectionPaths == null) return null;

    Set<UsageTarget> targets = new THashSet<UsageTarget>();
    for (TreePath selectionPath : selectionPaths) {
      Object lastPathComponent = selectionPath.getLastPathComponent();
      if (lastPathComponent instanceof UsageTargetNode) {
        UsageTargetNode usageTargetNode = (UsageTargetNode) lastPathComponent;
        UsageTarget target = usageTargetNode.getTarget();
        if (target != null && target.isValid()) {
          targets.add(target);
        }
      }
    }

    return targets.isEmpty() ? null : targets.toArray(new UsageTarget[targets.size()]);
  }
 @NotNull
 private List<Navigatable> getNavigatables() {
   TreePath[] paths = myTree.getSelectionPaths();
   if (paths == null) return Collections.emptyList();
   final ArrayList<Navigatable> navigatables = new ArrayList<Navigatable>();
   for (TreePath path : paths) {
     Object lastPathComponent = path.getLastPathComponent();
     if (lastPathComponent instanceof DefaultMutableTreeNode) {
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) lastPathComponent;
       Object userObject = node.getUserObject();
       if (userObject instanceof Navigatable) {
         navigatables.add((Navigatable) userObject);
       } else if (node instanceof Navigatable) {
         navigatables.add((Navigatable) node);
       }
     }
   }
   return navigatables;
 }
  private void reset(
      final Keymap keymap,
      final QuickList[] allQuickLists,
      String filter,
      @Nullable KeyboardShortcut shortcut) {
    myKeymap = keymap;

    final PathsKeeper pathsKeeper = new PathsKeeper();
    pathsKeeper.storePaths();

    myRoot.removeAllChildren();

    ActionManager actionManager = ActionManager.getInstance();
    Project project =
        CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myComponent));
    Group mainGroup =
        ActionsTreeUtil.createMainGroup(
            project,
            myKeymap,
            allQuickLists,
            filter,
            true,
            ActionsTreeUtil.isActionFiltered(actionManager, myKeymap, shortcut, filter, true));
    if ((filter != null && filter.length() > 0 || shortcut != null)
        && mainGroup.initIds().isEmpty()) {
      mainGroup =
          ActionsTreeUtil.createMainGroup(
              project,
              myKeymap,
              allQuickLists,
              filter,
              false,
              ActionsTreeUtil.isActionFiltered(actionManager, myKeymap, shortcut, filter, false));
    }
    myRoot = ActionsTreeUtil.createNode(mainGroup);
    myMainGroup = mainGroup;
    MyModel model = (MyModel) myTree.getModel();
    model.setRoot(myRoot);
    model.nodeStructureChanged(myRoot);

    pathsKeeper.restorePaths();
  }
 private void rulesChanged() {
   ApplicationManager.getApplication().assertIsDispatchThread();
   final ArrayList<UsageState> states = new ArrayList<UsageState>();
   captureUsagesExpandState(new TreePath(myTree.getModel().getRoot()), states);
   final List<Usage> allUsages = new ArrayList<Usage>(myUsageNodes.keySet());
   Collections.sort(allUsages, USAGE_COMPARATOR);
   final Set<Usage> excludedUsages = getExcludedUsages();
   reset();
   myBuilder.setGroupingRules(getActiveGroupingRules(myProject));
   myBuilder.setFilteringRules(getActiveFilteringRules(myProject));
   ApplicationManager.getApplication()
       .runReadAction(
           new Runnable() {
             @Override
             public void run() {
               for (Usage usage : allUsages) {
                 if (!usage.isValid()) {
                   continue;
                 }
                 if (usage instanceof MergeableUsage) {
                   ((MergeableUsage) usage).reset();
                 }
                 appendUsage(usage);
               }
             }
           });
   excludeUsages(excludedUsages.toArray(new Usage[excludedUsages.size()]));
   if (myCentralPanel != null) {
     setupCentralPanel();
   }
   SwingUtilities.invokeLater(
       new Runnable() {
         @Override
         public void run() {
           if (isDisposed) return;
           restoreUsageExpandState(states);
           updateImmediately();
         }
       });
 }
  public ActionsTree() {
    myRoot = new DefaultMutableTreeNode(ROOT);

    myTree =
        new Tree(new MyModel(myRoot)) {
          @Override
          public void paint(Graphics g) {
            super.paint(g);
            Rectangle visibleRect = getVisibleRect();
            Rectangle clip = g.getClipBounds();
            for (int row = 0; row < getRowCount(); row++) {
              Rectangle rowBounds = getRowBounds(row);
              rowBounds.x = 0;
              rowBounds.width = Integer.MAX_VALUE;

              if (rowBounds.intersects(clip)) {
                Object node = getPathForRow(row).getLastPathComponent();

                if (node instanceof DefaultMutableTreeNode) {
                  Object data = ((DefaultMutableTreeNode) node).getUserObject();
                  Rectangle fullRowRect =
                      new Rectangle(
                          visibleRect.x, rowBounds.y, visibleRect.width, rowBounds.height);
                  paintRowData(this, data, fullRowRect, (Graphics2D) g);
                }
              }
            }
          }
        };
    myTree.setRootVisible(false);
    myTree.setShowsRootHandles(true);

    myTree.putClientProperty(WideSelectionTreeUI.STRIPED_CLIENT_PROPERTY, Boolean.TRUE);
    myTree.setCellRenderer(new KeymapsRenderer());
    myTree.addMouseMotionListener(
        new MouseMotionAdapter() {
          @Override
          public void mouseMoved(MouseEvent e) {
            String description = getDescription(e);
            if (description != null) {
              ActionMenu.showDescriptionInStatusBar(true, myTree, description);
            } else {
              ActionMenu.showDescriptionInStatusBar(false, myTree, null);
            }
          }

          @Nullable
          private String getDescription(@NotNull MouseEvent e) {
            TreePath path = myTree.getPathForLocation(e.getX(), e.getY());
            if (path == null) return null;

            DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
            if (node == null) return null;

            Object userObject = node.getUserObject();
            if (!(userObject instanceof String)) return null;

            String actionId = (String) userObject;
            AnAction action = ActionManager.getInstance().getActionOrStub(actionId);
            if (action == null) return null;

            return action.getTemplatePresentation().getDescription();
          }
        });

    myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

    myComponent =
        ScrollPaneFactory.createScrollPane(
            myTree,
            ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
  }
 @Nullable
 private Object[] getSelectedTreeElements() {
   final JTree tree = getTree();
   return tree != null ? convertPathsToTreeElements(tree.getSelectionPaths()) : null;
 }
 @Nullable
 private Object getSelectedObject() {
   TreePath selectionPath = myTree.getSelectionPath();
   if (selectionPath == null) return null;
   return ((DefaultMutableTreeNode) selectionPath.getLastPathComponent()).getUserObject();
 }
 public void addTreeSelectionListener(TreeSelectionListener l) {
   myTree.getSelectionModel().addTreeSelectionListener(l);
 }