public VcsLogGraphTable(
      @NotNull VcsLogUiImpl UI,
      @NotNull final VcsLogDataHolder logDataHolder,
      @NotNull VisiblePack initialDataPack) {
    super();
    myUI = UI;
    myLogDataHolder = logDataHolder;
    myGraphCommitCellRenderer = new GraphCommitCellRender(logDataHolder, myGraphCellPainter, this);

    setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI));
    setDefaultRenderer(GraphCommitCell.class, myGraphCommitCellRenderer);
    setDefaultRenderer(String.class, new StringCellRenderer());

    setShowHorizontalLines(false);
    setIntercellSpacing(JBUI.emptySize());

    MouseAdapter mouseAdapter = new MyMouseAdapter();
    addMouseMotionListener(mouseAdapter);
    addMouseListener(mouseAdapter);
    MyHeaderMouseAdapter headerAdapter = new MyHeaderMouseAdapter();
    getTableHeader().addMouseListener(headerAdapter);
    getTableHeader().addMouseMotionListener(headerAdapter);

    getTableHeader().setReorderingAllowed(false);

    PopupHandler.installPopupHandler(
        this, VcsLogActionPlaces.POPUP_ACTION_GROUP, VcsLogActionPlaces.VCS_LOG_TABLE_PLACE);
    ScrollingUtil.installActions(this, false);

    GraphTableModel model = new GraphTableModel(initialDataPack, myLogDataHolder, myUI);
    setModel(model);
    initColumnSize();
  }
 protected void initTree() {
   ((DefaultTreeModel) myTree.getModel()).setRoot(myRoot);
   myTree.setRootVisible(false);
   myTree.setShowsRootHandles(true);
   UIUtil.setLineStyleAngled(myTree);
   TreeUtil.installActions(myTree);
   myTree.setCellRenderer(
       new ColoredTreeCellRenderer() {
         public void customizeCellRenderer(
             JTree tree,
             Object value,
             boolean selected,
             boolean expanded,
             boolean leaf,
             int row,
             boolean hasFocus) {
           if (value instanceof MyNode) {
             final MyNode node = ((MyNode) value);
             setIcon(node.getIcon(expanded));
             final Font font = UIUtil.getTreeFont();
             if (node.isDisplayInBold()) {
               setFont(font.deriveFont(Font.BOLD));
             } else {
               setFont(font.deriveFont(Font.PLAIN));
             }
             append(
                 node.getDisplayName(),
                 node.isDisplayInBold()
                     ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES
                     : SimpleTextAttributes.REGULAR_ATTRIBUTES);
           }
         }
       });
   initToolbar();
   ArrayList<AnAction> actions = createActions(true);
   if (actions != null) {
     final DefaultActionGroup group = new DefaultActionGroup();
     for (AnAction action : actions) {
       group.add(action);
     }
     actions = getAdditionalActions();
     if (actions != null) {
       group.addSeparator();
       for (AnAction action : actions) {
         group.add(action);
       }
     }
     PopupHandler.installPopupHandler(
         myTree,
         group,
         ActionPlaces.UNKNOWN,
         ActionManager.getInstance()); // popup should follow the selection
   }
 }
  private void initTree(final MyTree tree, boolean isRightTree) {
    tree.setCellRenderer(new MyTreeCellRenderer());
    tree.setRootVisible(false);
    tree.setShowsRootHandles(true);
    UIUtil.setLineStyleAngled(tree);

    TreeUtil.installActions(tree);
    SmartExpander.installOn(tree);
    EditSourceOnDoubleClickHandler.install(tree);
    new TreeSpeedSearch(tree);

    PopupHandler.installUnknownPopupHandler(
        tree, createTreePopupActions(isRightTree), ActionManager.getInstance());
  }
  private void initTree(Tree tree) {
    tree.setCellRenderer(new MyTreeCellRenderer());
    tree.setRootVisible(false);
    tree.setShowsRootHandles(true);
    tree.setLineStyleAngled();

    TreeUtil.installActions(tree);
    SmartExpander.installOn(tree);
    new TreeSpeedSearch(tree);
    tree.addTreeWillExpandListener(
        new TreeWillExpandListener() {
          @Override
          public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
            ((PackageDependenciesNode) event.getPath().getLastPathComponent()).sortChildren();
          }

          @Override
          public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {}
        });

    PopupHandler.installUnknownPopupHandler(
        tree, createTreePopupActions(), ActionManager.getInstance());
  }
  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.
  }
  public ClasspathPanelImpl(ModuleConfigurationState state) {
    super(new BorderLayout());

    myState = state;
    myModel = new ClasspathTableModel(state, getStructureConfigurableContext());
    myEntryTable =
        new JBTable(myModel) {
          @Override
          protected TableRowSorter<TableModel> createRowSorter(TableModel model) {
            return new DefaultColumnInfoBasedRowSorter(model) {
              @Override
              public void toggleSortOrder(int column) {
                if (isSortable(column)) {
                  SortKey oldKey = ContainerUtil.getFirstItem(getSortKeys());
                  SortOrder oldOrder;
                  if (oldKey == null || oldKey.getColumn() != column) {
                    oldOrder = SortOrder.UNSORTED;
                  } else {
                    oldOrder = oldKey.getSortOrder();
                  }
                  setSortKeys(
                      Collections.singletonList(new SortKey(column, getNextSortOrder(oldOrder))));
                }
              }
            };
          }
        };
    myEntryTable.setShowGrid(false);
    myEntryTable.setDragEnabled(false);
    myEntryTable.setIntercellSpacing(new Dimension(0, 0));

    myEntryTable.setDefaultRenderer(
        ClasspathTableItem.class, new TableItemRenderer(getStructureConfigurableContext()));
    myEntryTable.setDefaultRenderer(
        Boolean.class, new ExportFlagRenderer(myEntryTable.getDefaultRenderer(Boolean.class)));

    JComboBox scopeEditor =
        new ComboBox(new EnumComboBoxModel<DependencyScope>(DependencyScope.class));
    myEntryTable.setDefaultEditor(DependencyScope.class, new DefaultCellEditor(scopeEditor));
    myEntryTable.setDefaultRenderer(
        DependencyScope.class,
        new ComboBoxTableRenderer<DependencyScope>(DependencyScope.values()) {
          @Override
          protected String getTextFor(@NotNull final DependencyScope value) {
            return value.getDisplayName();
          }
        });

    myEntryTable.setTransferHandler(
        new TransferHandler() {
          @Nullable
          @Override
          protected Transferable createTransferable(JComponent c) {
            OrderEntry entry = getSelectedEntry();
            if (entry == null) return null;
            String text = entry.getPresentableName();
            return new TextTransferable(text);
          }

          @Override
          public int getSourceActions(JComponent c) {
            return COPY;
          }
        });

    myEntryTable
        .getSelectionModel()
        .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

    new SpeedSearchBase<JBTable>(myEntryTable) {
      @Override
      public int getSelectedIndex() {
        return myEntryTable.getSelectedRow();
      }

      @Override
      protected int convertIndexToModel(int viewIndex) {
        return myEntryTable.convertRowIndexToModel(viewIndex);
      }

      @Override
      public Object[] getAllElements() {
        final int count = myModel.getRowCount();
        Object[] elements = new Object[count];
        for (int idx = 0; idx < count; idx++) {
          elements[idx] = myModel.getItem(idx);
        }
        return elements;
      }

      @Override
      public String getElementText(Object element) {
        return getCellAppearance(
                (ClasspathTableItem<?>) element, getStructureConfigurableContext(), false)
            .getText();
      }

      @Override
      public void selectElement(Object element, String selectedText) {
        final int count = myModel.getRowCount();
        for (int row = 0; row < count; row++) {
          if (element.equals(myModel.getItem(row))) {
            final int viewRow = myEntryTable.convertRowIndexToView(row);
            myEntryTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
            TableUtil.scrollSelectionToVisible(myEntryTable);
            break;
          }
        }
      }
    };
    setFixedColumnWidth(ClasspathTableModel.EXPORT_COLUMN);
    setFixedColumnWidth(ClasspathTableModel.SCOPE_COLUMN); // leave space for combobox border

    myEntryTable.registerKeyboardAction(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            final int[] selectedRows = myEntryTable.getSelectedRows();
            boolean currentlyMarked = true;
            for (final int selectedRow : selectedRows) {
              final ClasspathTableItem<?> item = getItemAt(selectedRow);
              if (selectedRow < 0 || !item.isExportable()) {
                return;
              }
              currentlyMarked &= item.isExported();
            }
            for (final int selectedRow : selectedRows) {
              getItemAt(selectedRow).setExported(!currentlyMarked);
            }
            myModel.fireTableDataChanged();
            TableUtil.selectRows(myEntryTable, selectedRows);
          }
        },
        KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
        WHEN_FOCUSED);

    myEditButton =
        new AnActionButton(
            ProjectBundle.message("module.classpath.button.edit"), null, IconUtil.getEditIcon()) {
          @Override
          public void actionPerformed(@NotNull AnActionEvent e) {
            doEdit();
          }

          @Override
          public boolean isEnabled() {
            ClasspathTableItem<?> selectedItem = getSelectedItem();
            return selectedItem != null && selectedItem.isEditable();
          }

          @Override
          public boolean isDumbAware() {
            return true;
          }
        };
    add(createTableWithButtons(), BorderLayout.CENTER);

    if (myEntryTable.getRowCount() > 0) {
      myEntryTable.getSelectionModel().setSelectionInterval(0, 0);
    }

    new DoubleClickListener() {
      @Override
      protected boolean onDoubleClick(MouseEvent e) {
        navigate(true);
        return true;
      }
    }.installOn(myEntryTable);

    DefaultActionGroup actionGroup = new DefaultActionGroup();
    final AnAction navigateAction =
        new AnAction(ProjectBundle.message("classpath.panel.navigate.action.text")) {
          @Override
          public void actionPerformed(@NotNull AnActionEvent e) {
            navigate(false);
          }

          @Override
          public void update(@NotNull AnActionEvent e) {
            final Presentation presentation = e.getPresentation();
            presentation.setEnabled(false);
            final OrderEntry entry = getSelectedEntry();
            if (entry != null && entry.isValid()) {
              if (!(entry instanceof ModuleSourceOrderEntry)) {
                presentation.setEnabled(true);
              }
            }
          }
        };
    navigateAction.registerCustomShortcutSet(
        ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(),
        myEntryTable);
    actionGroup.add(myEditButton);
    actionGroup.add(myRemoveButton);
    actionGroup.add(navigateAction);
    actionGroup.add(new InlineModuleDependencyAction(this));
    actionGroup.add(new MyFindUsagesAction());
    actionGroup.add(new AnalyzeDependencyAction());
    addChangeLibraryLevelAction(actionGroup, LibraryTablesRegistrar.PROJECT_LEVEL);
    addChangeLibraryLevelAction(actionGroup, LibraryTablesRegistrar.APPLICATION_LEVEL);
    addChangeLibraryLevelAction(actionGroup, LibraryTableImplUtil.MODULE_LEVEL);
    PopupHandler.installPopupHandler(
        myEntryTable, actionGroup, ActionPlaces.UNKNOWN, ActionManager.getInstance());
  }