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);
      }
    }
  }
 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;
 }
 private void updateImmediately() {
   if (myProject.isDisposed()) return;
   checkNodeValidity((DefaultMutableTreeNode) myTree.getModel().getRoot());
   if (myUsagePreviewPanel != null) {
     myUsagePreviewPanel.updateLayout(getSelectedUsageInfos());
   }
 }
  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();
  }
 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);
   }
 }
 @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;
 }
 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 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 DefaultMutableTreeNode getModelRoot() {
   return (DefaultMutableTreeNode) myTree.getModel().getRoot();
 }