private void showNode(@NotNull final UsageNode node) {
   if (!myPresentation.isDetachedMode()) {
     UIUtil.invokeLaterIfNeeded(
         new Runnable() {
           @Override
           public void run() {
             if (isDisposed) return;
             TreePath usagePath = new TreePath(node.getPath());
             myTree.expandPath(usagePath.getParentPath());
             TreeUtil.selectPath(myTree, usagePath);
           }
         });
   }
 }
 public void setSearchInProgress(boolean searchInProgress) {
   mySearchInProgress = searchInProgress;
   if (!myPresentation.isDetachedMode()) {
     UIUtil.invokeLaterIfNeeded(
         new Runnable() {
           @Override
           public void run() {
             if (isDisposed) return;
             final UsageNode firstUsageNode = myModel.getFirstUsageNode();
             if (firstUsageNode != null) {
               showNode(firstUsageNode);
             }
           }
         });
   }
 }
 @Override
 public void removeUsage(@NotNull Usage usage) {
   final UsageNode node = myUsageNodes.remove(usage);
   if (node != NULL_NODE && node != null && !myPresentation.isDetachedMode()) {
     UIUtil.invokeLaterIfNeeded(
         new Runnable() {
           @Override
           public void run() {
             if (isDisposed) return;
             TreeModel treeModel = myTree.getModel();
             ((DefaultTreeModel) treeModel).removeNodeFromParent(node);
             ((GroupNode) myTree.getModel().getRoot()).removeUsage(node);
           }
         });
   }
 }
  private void reset() {
    ApplicationManager.getApplication().assertIsDispatchThread();

    myUsageNodes.clear();
    myIsFirstVisibleUsageFound = false;

    myModel.reset();
    if (!myPresentation.isDetachedMode()) {
      SwingUtilities.invokeLater(
          new Runnable() {
            @Override
            public void run() {
              if (isDisposed) return;
              TreeUtil.expand(myTree, 2);
            }
          });
    }
  }
 @Override
 public void addButtonToLowerPane(@NotNull Runnable runnable, @NotNull String text) {
   int index = myButtonPanel.getComponentCount();
   if (index > 0 && myPresentation.isShowCancelButton()) index--;
   myButtonPanel.addButtonRunnable(index, runnable, text);
 }
  public UsageViewImpl(
      @NotNull final Project project,
      @NotNull UsageViewPresentation presentation,
      @NotNull UsageTarget[] targets,
      Factory<UsageSearcher> usageSearcherFactory) {
    myPresentation = presentation;
    myTargets = targets;
    myUsageSearcherFactory = usageSearcherFactory;
    myProject = project;
    myTree =
        new Tree() {
          {
            ToolTipManager.sharedInstance().registerComponent(this);
          }

          @Override
          public String getToolTipText(MouseEvent e) {
            TreePath path = getPathForLocation(e.getX(), e.getY());
            if (path != null) {
              if (getCellRenderer() instanceof UsageViewTreeCellRenderer) {
                return UsageViewTreeCellRenderer.getTooltipText(path.getLastPathComponent());
              }
            }
            return null;
          }

          @Override
          public boolean isPathEditable(final TreePath path) {
            return path.getLastPathComponent() instanceof UsageViewTreeModelBuilder.TargetsRootNode;
          }
        };
    myRootPanel = new MyPanel(myTree);
    Disposer.register(this, myRootPanel);
    myModelTracker = new UsageModelTracker(project);
    Disposer.register(this, myModelTracker);

    myModel = new UsageViewTreeModelBuilder(myPresentation, targets);
    myRoot = (GroupNode) myModel.getRoot();
    myBuilder =
        new UsageNodeTreeBuilder(
            myTargets, getActiveGroupingRules(project), getActiveFilteringRules(project), myRoot);

    final MessageBusConnection messageBusConnection = myProject.getMessageBus().connect(this);
    messageBusConnection.subscribe(
        UsageFilteringRuleProvider.RULES_CHANGED,
        new Runnable() {
          @Override
          public void run() {
            rulesChanged();
          }
        });

    if (!myPresentation.isDetachedMode()) {
      UIUtil.invokeLaterIfNeeded(
          new Runnable() {
            @Override
            public void run() {
              // lock here to avoid concurrent execution of this init and dispose in other thread
              synchronized (lock) {
                if (isDisposed) return;
                myTree.setModel(myModel);

                myRootPanel.setLayout(new BorderLayout());

                final SimpleToolWindowPanel twPanel = new SimpleToolWindowPanel(false, true);
                myRootPanel.add(twPanel, BorderLayout.CENTER);

                JPanel toolbarPanel = new JPanel(new BorderLayout());
                toolbarPanel.add(createActionsToolbar(), BorderLayout.WEST);
                toolbarPanel.add(createFiltersToolbar(), BorderLayout.CENTER);
                twPanel.setToolbar(toolbarPanel);

                myCentralPanel = new JPanel();
                myCentralPanel.setLayout(new BorderLayout());
                setupCentralPanel();

                initTree();
                twPanel.setContent(myCentralPanel);

                myTree.setCellRenderer(new UsageViewTreeCellRenderer(UsageViewImpl.this));
                collapseAll();

                myModelTracker.addListener(UsageViewImpl.this);

                if (myPresentation.isShowCancelButton()) {
                  addButtonToLowerPane(
                      new Runnable() {
                        @Override
                        public void run() {
                          close();
                        }
                      },
                      UsageViewBundle.message("usage.view.cancel.button"));
                }

                myTree
                    .getSelectionModel()
                    .addTreeSelectionListener(
                        new TreeSelectionListener() {
                          @Override
                          public void valueChanged(final TreeSelectionEvent e) {
                            SwingUtilities.invokeLater(
                                new Runnable() {
                                  @Override
                                  public void run() {
                                    if (isDisposed) return;
                                    List<UsageInfo> infos = getSelectedUsageInfos();
                                    if (infos != null && myUsagePreviewPanel != null) {
                                      myUsagePreviewPanel.updateLayout(infos);
                                    }
                                  }
                                });
                          }
                        });
              }
            }
          });
    }
    myTransferToEDTQueue =
        new TransferToEDTQueue<Usage>(
            "Insert usages",
            new Processor<Usage>() {
              @Override
              public boolean process(Usage usage) {
                appendUsage(usage);
                return true;
              }
            },
            new Condition<Object>() {
              @Override
              public boolean value(Object o) {
                return isDisposed
                    || project.isDisposed()
                    || com.intellij.usages.UsageViewManager.getInstance(project)
                        .searchHasBeenCancelled();
              }
            },
            200);
  }