Navigation Bar related refactorings: IDEADEV-40444, IDEADEV-40412, WI-121, IDEA-11944

This commit is contained in:
Maxim Shafirov
2009-09-17 20:13:10 +04:00
parent 105b6a850c
commit d456d3fe37
8 changed files with 313 additions and 501 deletions
@@ -20,7 +20,6 @@ import com.intellij.openapi.roots.ModuleFileIndex;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.FileStatusManager;
@@ -41,23 +40,16 @@ import java.util.List;
public class NavBarModel {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.navigationToolbar.NavBarModel");
private final ArrayList<Object> myModel = new ArrayList<Object>();
private List<Object> myModel = Collections.emptyList();
private int mySelectedIndex;
private final Project myProject;
private final MyObservable myObservable = new MyObservable();
private final static SimpleTextAttributes WOLFED = new SimpleTextAttributes(null, null, Color.red, SimpleTextAttributes.STYLE_WAVED);
private final NavBarModelListener myNotificator;
public NavBarModel(final Project project) {
myProject = project;
}
public void addElement(Object object) {
myModel.add(object);
}
public void removeAllElements() {
myModel.clear();
myNotificator = project.getMessageBus().syncPublisher(NavBarModelListener.NAV_BAR);
}
public int getSelectedIndex() {
@@ -85,49 +77,40 @@ public class NavBarModel {
return myModel.isEmpty();
}
public int getIndexByMode(int index) {
public int getIndexByModel(int index) {
if (index < 0) return myModel.size() + index;
if (index >= myModel.size() && myModel.size() > 0) return index % myModel.size();
return index;
}
protected boolean updateModel(DataContext dataContext) {
if (LaterInvocator.isInModalContext()) return false;
protected void updateModel(DataContext dataContext) {
if (LaterInvocator.isInModalContext()) return;
PsiElement psiElement = LangDataKeys.PSI_FILE.getData(dataContext);
if (psiElement == null) {
psiElement = LangDataKeys.PSI_ELEMENT.getData(dataContext);
}
psiElement = normalize(psiElement);
if (psiElement != null && psiElement.isValid()) {
return updateModel(psiElement);
updateModel(psiElement);
}
else {
if (UISettings.getInstance().SHOW_NAVIGATION_BAR) {
return false;
}
if (UISettings.getInstance().SHOW_NAVIGATION_BAR) return;
Object moduleOrProject = LangDataKeys.MODULE.getData(dataContext);
if (moduleOrProject == null) {
moduleOrProject = LangDataKeys.PROJECT.getData(dataContext);
}
if (moduleOrProject != null) {
if (size() == 1 && getElement(0) == moduleOrProject) { //no need to update
return false;
}
removeAllElements();
addElement(moduleOrProject);
setModel(Collections.singletonList(moduleOrProject));
}
}
return true;
}
protected boolean updateModel(final PsiElement psiElement) {
final int oldModelSize = size();
final List<Object> oldModel = new ArrayList<Object>();
for (int i = 0; i < oldModelSize; i++) {
oldModel.add(getElement(i));
}
removeAllElements();
//addElement(myProject);
protected void updateModel(final PsiElement psiElement) {
final Set<VirtualFile> roots = new HashSet<VirtualFile>();
final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject);
final ProjectFileIndex projectFileIndex = projectRootManager.getFileIndex();
@@ -139,19 +122,24 @@ public class NavBarModel {
}
}
final List<Object> updatedModel = new ArrayList<Object>();
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
traverseToRoot(psiElement, roots);
traverseToRoot(psiElement, roots, updatedModel);
}
});
if (oldModelSize == size()) {
for (int i = 0; i < oldModelSize; i++) {
if (!Comparing.equal(oldModel.get(i), getElement(i))) return true;
}
return false;
}
else {
return true;
setModel(updatedModel);
}
private void setModel(List<Object> model) {
if (!model.equals(myModel)) {
myModel = model;
myNotificator.modelChanged();
mySelectedIndex = myModel.size() - 1;
myNotificator.selectionChanged();
}
}
@@ -160,13 +148,14 @@ public class NavBarModel {
updateModel((PsiElement)object);
}
else if (object instanceof Module) {
removeAllElements();
addElement(myProject);
addElement(object);
List<Object> l = new ArrayList<Object>();
l.add(myProject);
l.add(object);
setModel(l);
}
}
private void traverseToRoot(@NotNull PsiElement psiElement, Set<VirtualFile> roots) {
private void traverseToRoot(@NotNull PsiElement psiElement, Set<VirtualFile> roots, List<Object> model) {
if (!psiElement.isValid()) return;
final PsiFile containingFile = psiElement.getContainingFile();
if (containingFile != null &&
@@ -179,7 +168,7 @@ public class NavBarModel {
}
final PsiDirectory containingDirectory = containingFile.getContainingDirectory();
if (containingDirectory != null) {
traverseToRoot(containingDirectory, roots);
traverseToRoot(containingDirectory, roots, model);
}
}
else if (psiElement instanceof PsiDirectory) {
@@ -197,7 +186,7 @@ public class NavBarModel {
if (parentDirectory != null) {
traverseToRoot(parentDirectory, roots);
traverseToRoot(parentDirectory, roots, model);
}
}
}
@@ -216,7 +205,7 @@ public class NavBarModel {
if (parentVFile != null && !roots.contains(parentVFile)) {
final PsiDirectory parentDirectory = psiManager.findDirectory(parentVFile);
if (parentDirectory != null) {
traverseToRoot(parentDirectory, roots);
traverseToRoot(parentDirectory, roots, model);
}
}
}
@@ -225,11 +214,11 @@ public class NavBarModel {
for (final NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
final PsiElement parent = modelExtension.getParent(el);
if (parent != null) {
traverseToRoot(parent, roots);
traverseToRoot(parent, roots, model);
}
}
}
addElement(resultElement);
model.add(resultElement);
}
@@ -424,19 +413,15 @@ public class NavBarModel {
return result;
}
public int indexOf(final Object object) {
return myModel.indexOf(object);
}
public Object get(final int index) {
return myModel.get(index);
}
public boolean setSelectedIndex(final int selectedIndex) {
if (mySelectedIndex == selectedIndex) return false;
mySelectedIndex = selectedIndex;
myObservable.fireChange();
return true;
public void setSelectedIndex(final int selectedIndex) {
if (mySelectedIndex != selectedIndex) {
mySelectedIndex = selectedIndex;
myNotificator.selectionChanged();
}
}
private static final class SiblingsComparator implements Comparator<Object> {
@@ -471,20 +456,4 @@ public class NavBarModel {
return null;
}
}
public void addSelectionObserver(Observer observer) {
myObservable.addObserver(observer);
}
public void removeSelectionObserver(Observer observer) {
myObservable.deleteObserver(observer);
}
private static class MyObservable extends Observable {
public void fireChange() {
setChanged();
notifyObservers();
}
}
}
@@ -0,0 +1,13 @@
/*
* @author max
*/
package com.intellij.ide.navigationToolbar;
import com.intellij.util.messages.Topic;
public interface NavBarModelListener {
Topic<NavBarModelListener> NAV_BAR = Topic.create("Navigation Bar model changes", NavBarModelListener.class);
void modelChanged();
void selectionChanged();
}
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.ide.CopyPasteDelegator;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeView;
import com.intellij.ide.impl.DataManagerImpl;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
import com.intellij.ide.ui.customization.CustomActionsSchema;
@@ -28,7 +27,6 @@ import com.intellij.ide.util.DeleteHandler;
import com.intellij.ide.util.DirectoryChooserUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.impl.WeakTimerListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
@@ -42,7 +40,6 @@ import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider;
import com.intellij.openapi.ui.popup.IconButton;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
@@ -55,7 +52,6 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.pom.Navigatable;
import com.intellij.problems.WolfTheProblemSolver;
import com.intellij.psi.*;
@@ -72,74 +68,43 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
/**
* User: anna
* Date: 03-Nov-2005
*/
public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
private final Object myUpdateLock = new Object();
private static final Icon LEFT_ICON = IconLoader.getIcon("/general/splitLeft.png");
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.navigationToolbar.NavigationToolbarPanel");
/*private static final Icon LEFT_ICON = IconLoader.getIcon("/general/splitLeft.png");
private static final Icon RIGHT_ICON = IconLoader.getIcon("/general/splitRight.png");
*/
private final ArrayList<MyItemLabel> myList = new ArrayList<MyItemLabel>();
private final ArrayList<MyCompositeLabel> myList = new ArrayList<MyCompositeLabel>();
private int myFirstIndex = 0;
private final InplaceButton myLeftButton = new InplaceButton(new IconButton("Scroll Left", LEFT_ICON), new ActionListener() {
public void actionPerformed(final ActionEvent e) {
selectLast();
shiftFocus(-1);
}
});
private final InplaceButton myRightButton = new InplaceButton(new IconButton("Scroll Right", RIGHT_ICON), new ActionListener() {
public void actionPerformed(final ActionEvent e) {
selectLast();
shiftFocus(1);
}
});
private final JPanel myScrollablePanel = new JPanel(new GridBagLayout());
private int myPreferredWidth;
private final NavBarModel myModel;
private final Project myProject;
private final MyPsiTreeChangeAdapter myPsiTreeChangeAdapter = new MyPsiTreeChangeAdapter();
private final MyProblemListener myProblemListener = new MyProblemListener();
private final MyFileStatusListener myFileStatusListener = new MyFileStatusListener();
private final MyTimerListener myTimerListener = new MyTimerListener();
private Runnable myDetacher;
private final ModuleDeleteProvider myDeleteModuleProvider = new ModuleDeleteProvider();
private final IdeView myIdeView = new MyIdeView();
private final CopyPasteDelegator myCopyPasteDelegator;
private LightweightHint myHint = null;
private ListPopupImpl myNodePopup = null;
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.navigationToolbar.NavigationToolbarPanel");
private MessageBusConnection myConnection;
private WeakTimerListener myWeakTimerListener;
private static final int GAP_BETWEEN_LIST_ITEMS = 10;
private final Alarm myListUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private final Alarm myModelUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
public NavBarPanel(final Project project) {
super(new FlowLayout(FlowLayout.LEFT, 5, 0));
myProject = project;
myModel = new NavBarModel(myProject);
setLayout(new BorderLayout());
setBackground(UIUtil.getListBackground());
myScrollablePanel.setBackground(UIUtil.getListBackground());
add(myScrollablePanel, BorderLayout.CENTER);
add(myLeftButton, BorderLayout.WEST);
myLeftButton.setVisible(false);
myLeftButton.setBorder(new EmptyBorder(0, 2, 0, 2));
add(myRightButton, BorderLayout.EAST);
myRightButton.setVisible(false);
myRightButton.setBorder(new EmptyBorder(0, 2, 0, 2));
setOpaque(true);
PopupHandler.installPopupHandler(this, IdeActions.GROUP_PROJECT_VIEW_POPUP, ActionPlaces.NAVIGATION_BAR);
@@ -190,12 +155,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
registerKeyboardAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
final Object o = myModel.getSelectedValue();
if (myModel.hasChildren(o)) {
navigateInsideBar(o);
}
else {
doubleClick(myModel.getSelectedIndex());
}
navigateInsideBar(o);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), WHEN_FOCUSED);
@@ -207,13 +167,16 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), WHEN_FOCUSED);
addFocusListener(new FocusListener() {
public void focusGained(final FocusEvent e) {}
public void focusGained(final FocusEvent e) {
updateItems();
}
public void focusLost(final FocusEvent e) {
if (myProject.isDisposed()) {
hideHint();
return;
}
// required invokeLater since in current call sequence KeyboardFocusManager is not initialized yet
// but future focused component
SwingUtilities.invokeLater(new Runnable() {
@@ -226,15 +189,16 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
installBorder(-1);
updateList();
myCopyPasteDelegator = new CopyPasteDelegator(myProject, NavBarPanel.this) {
@NotNull
protected PsiElement[] getSelectedElements() {
final PsiElement element = getSelectedElement(PsiElement.class);
return element == null ? PsiElement.EMPTY_ARRAY : new PsiElement[]{element};
}
};
updateModel();
updateList();
}
private void processFocusLost(final FocusEvent e) {
@@ -247,95 +211,86 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
hideHint();
}
}
updateItems();
}
private void selectLast() {
if (myModel.getSelectedIndex() == -1 && !myModel.isEmpty()) {
myModel.setSelectedIndex(myModel.size() - 1);
IdeFocusManager.getInstance(myProject).requestFocus(myList.get(myModel.getSelectedIndex()), true);
private void updateItems() {
for (MyItemLabel item : myList) {
item.update();
}
}
public void select() {
updateModel();
updateList();
if (!myList.isEmpty()) {
myModel.setSelectedIndex(myList.size() - 1);
rebuildComponent();
scrollSelectionToVisible(1);
IdeFocusManager.getInstance(myProject).requestFocus(this, true);
}
}
private void shiftFocus(int direction) {
if (myModel.setSelectedIndex(myModel.getIndexByMode(myModel.getSelectedIndex() + direction))) {
scrollSelectionToVisible(direction);
}
myModel.setSelectedIndex(myModel.getIndexByModel(myModel.getSelectedIndex() + direction));
}
private void scrollSelectionToVisible(final int direction) {
private void scrollSelectionToVisible() {
final int selectedIndex = myModel.getSelectedIndex();
if (selectedIndex == -1 || selectedIndex >= myList.size()) return;
final int firstIndex = myFirstIndex;
while (!myList.get(selectedIndex).isShowing()) {
myFirstIndex = myModel.getIndexByMode(myFirstIndex + direction);
rebuildComponent();
if (firstIndex == myFirstIndex) break; //to be sure not to hang
}
setSize(getPreferredSize()); //not to miss right button && font corrections
repaint();
MyItemLabel selectedItem = myList.get(selectedIndex);
Rectangle rect = selectedItem.getBounds();
scrollRectToVisible(rect);
}
@Nullable
private MyCompositeLabel getItem(int index) {
private MyItemLabel getItem(int index) {
if (index != -1 && index < myList.size()) {
return myList.get(index);
}
return null;
}
/**
* to be invoked by alarm
*/
private void updateList() {
final DataManagerImpl dataManager = (DataManagerImpl)DataManager.getInstance();
final Component focusedComponent = WindowManagerEx.getInstanceEx().getFocusedComponent(myProject);
final JBPopup childPopup = JBPopupFactory.getInstance().getChildPopup(this);
final boolean nodePopupShowing = focusedComponent == null ||
focusedComponent == this ||
isAncestorOf(focusedComponent) ||
(myNodePopup != null && myNodePopup.isVisible());
if (nodePopupShowing || (childPopup != null && childPopup.isFocused())) {
immediateUpdateList(false);
}
else {
final DataContext dataContext = dataManager.getDataContextTest(this);
immediateUpdateList(myModel.updateModel(dataContext));
private void scheduleModelUpdate() {
myModelUpdateAlarm.cancelAllRequests();
if (!isInFloatingMode() && !isNodePopupShowing()) {
myModelUpdateAlarm.addRequest(new Runnable() {
public void run() {
if (myProject.isDisposed()) return;
updateModel();
}
}, 300);
}
}
private void immediateUpdateList(boolean update) {
synchronized (myUpdateLock) {
if (update) {
myFirstIndex = 0;
final int selectedIndex1 = -1;
myModel.setSelectedIndex(selectedIndex1);
myList.clear();
for (int index = 0; index < myModel.size(); index++) {
final Object object = myModel.get(index);
final Icon closedIcon = getIcon(object, false);
final Icon openIcon = getIcon(object, true);
final MyCompositeLabel label = new MyCompositeLabel(index,
wrapIcon(openIcon, closedIcon, index),
NavBarModel.getPresentableText(object, getWindow()),
myModel.getTextAttributes(object, false), myModel);
private boolean isInFloatingMode() {
return myHint != null && myHint.isVisible();
}
installActions(index, label);
myList.add(label);
}
rebuildComponent();
}
private void updateModel() {
DataContext context = DataManager.getInstance().getDataContext();
if (context.getData(DataConstants.IDE_VIEW) == myIdeView) return;
myModel.updateModel(context);
}
private void updateList() {
myList.clear();
for (int index = 0; index < myModel.size(); index++) {
final Object object = myModel.get(index);
final Icon closedIcon = getIcon(object, false);
final Icon openIcon = getIcon(object, true);
final MyItemLabel label =
new MyItemLabel(index, wrapIcon(openIcon, closedIcon, index), NavBarModel.getPresentableText(object, getWindow()),
myModel.getTextAttributes(object, false));
installActions(index, label);
myList.add(label);
}
rebuildComponent();
}
@Nullable
@@ -365,11 +320,11 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
private Icon wrapIcon(final Icon openIcon, final Icon closedIcon, final int idx) {
return new Icon() {
public void paintIcon(Component c, Graphics g, int x, int y) {
if (myModel.getSelectedIndex() != idx || myNodePopup == null || !myNodePopup.isVisible()) {
closedIcon.paintIcon(c, g, x, y);
if (myModel.getSelectedIndex() == idx && myNodePopup != null && myNodePopup.isVisible()) {
openIcon.paintIcon(c, g, x, y);
}
else {
openIcon.paintIcon(c, g, x, y);
closedIcon.paintIcon(c, g, x, y);
}
}
@@ -384,78 +339,20 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
private void rebuildComponent() {
myPreferredWidth = 0;
myScrollablePanel.removeAll();
myScrollablePanel.invalidate();
final GridBagConstraints gc = new GridBagConstraints(GridBagConstraints.RELATIVE, 1, 1, 1, 0, 1, GridBagConstraints.WEST,
GridBagConstraints.NONE,
new Insets(0, GAP_BETWEEN_LIST_ITEMS / 2, 0, GAP_BETWEEN_LIST_ITEMS / 2), 0, 0);
final MyCompositeLabel toBeContLabel = getDotsLabel();
final int additionalWidth = toBeContLabel.getPreferredSize().width;
final Window window = SwingUtilities.getWindowAncestor(this);
final int availableWidth = window != null ? window.getWidth() - 2 * LEFT_ICON.getIconWidth() - 2 * additionalWidth : 0;
int lastIndx = -1;
if (myModel.getSelectedIndex() != -1) {
myScrollablePanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
if (myFirstIndex > 0) {
final MyCompositeLabel preList = getDotsLabel();
myScrollablePanel.add(preList, gc);
myPreferredWidth += additionalWidth;
}
for (int i = myFirstIndex; i < myList.size(); i++) {
final MyCompositeLabel linkLabel = myList.get(i);
final int labelWidth = linkLabel.getPreferredSize().width;
if (myPreferredWidth + labelWidth < availableWidth) {
myScrollablePanel.add(linkLabel, gc);
myPreferredWidth += labelWidth + GAP_BETWEEN_LIST_ITEMS;
}
else {
myScrollablePanel.add(toBeContLabel, gc);
myPreferredWidth += additionalWidth;
lastIndx = i;
break;
}
}
gc.weightx = 1;
gc.fill = GridBagConstraints.HORIZONTAL;
myScrollablePanel.add(Box.createHorizontalBox(), gc);
removeAll();
for (MyItemLabel item : myList) {
add(item);
}
else if (!myModel.isEmpty()) {
myScrollablePanel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
gc.weightx = 1;
gc.fill = GridBagConstraints.HORIZONTAL;
myScrollablePanel.add(Box.createHorizontalBox(), gc);
gc.weightx = 0;
gc.fill = GridBagConstraints.NONE;
for (int i = myModel.size() - 1; i >= 0; i--) {
final MyCompositeLabel linkLabel = myList.get(i);
final int labelWidth = linkLabel.getPreferredSize().width;
if (availableWidth == 0 || myPreferredWidth + labelWidth < availableWidth) {
myScrollablePanel.add(linkLabel, gc);
myPreferredWidth += labelWidth + GAP_BETWEEN_LIST_ITEMS;
}
else {
myFirstIndex = i + 1;
myScrollablePanel.add(toBeContLabel, gc);
myPreferredWidth += additionalWidth;
break;
}
}
}
myPreferredWidth += 2 * LEFT_ICON.getIconWidth();
final boolean hasNavigationButtons = lastIndx > 0 || myFirstIndex > 0;
myLeftButton.setVisible(hasNavigationButtons);
myRightButton.setVisible(hasNavigationButtons);
revalidate();
repaint();
}
private MyCompositeLabel getDotsLabel() {
return new MyCompositeLabel(-1, null, "...", SimpleTextAttributes.REGULAR_ATTRIBUTES, myModel);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
scrollSelectionToVisible();
}
});
}
private Window getWindow() {
@@ -463,7 +360,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
// ------ NavBar actions -------------------------
private void installActions(final int index, final MyCompositeLabel component) {
private void installActions(final int index, final MyItemLabel component) {
ListenerUtil.addMouseListener(component, new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (!e.isConsumed() && !e.isPopupTrigger() && e.getClickCount() == 2) {
@@ -544,7 +441,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
private void ctrlClick(final int index) {
if (myNodePopup != null && myNodePopup.isVisible()) {
if (isNodePopupShowing()) {
cancelPopup();
if (myModel.getSelectedIndex() == index) {
return;
@@ -553,6 +450,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
final Object object = myModel.getElement(index);
final List<Object> objects = myModel.calcElementChildren(object);
if (!objects.isEmpty()) {
final Object[] siblings = new Object[objects.size()];
final Icon[] icons = new Icon[objects.size()];
@@ -560,23 +458,14 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
siblings[i] = objects.get(i);
icons[i] = getIcon(siblings[i], false);
}
final MyCompositeLabel item = getItem(index);
final MyItemLabel item = getItem(index);
LOG.assertTrue(item != null);
final BaseListPopupStep<Object> step = new BaseListPopupStep<Object>("", siblings, icons) {
public boolean isSpeedSearchEnabled() { return true; }
@NotNull public String getTextFor(final Object value) { return NavBarModel.getPresentableText(value, null);}
public boolean isSelectable(Object value) { return true; }
public PopupStep onChosen(final Object selectedValue, final boolean finalChoice) {
if (!myModel.hasChildren(selectedValue)) {
doubleClick(selectedValue);
}
else {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
navigateInsideBar(selectedValue);
}
});
}
navigateInsideBar(selectedValue);
return FINAL_CHOICE;
}
@@ -629,15 +518,19 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
}
});
validate();
myNodePopup.showUnderneathOf(item.getColoredComponent());
myNodePopup.showUnderneathOf(item);
}
repaint();
}
private void navigateInsideBar(Object object) {
private boolean isNodePopupShowing() {
return myNodePopup != null && myNodePopup.isVisible();
}
private void navigateInsideBar(final Object object) {
myModel.updateModel(object);
immediateUpdateList(true);
updateList();
myModel.setSelectedIndex(myList.size() - 1);
if (myHint != null) {
@@ -646,15 +539,23 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
myHint.setBounds(bounds.x, bounds.y, dimension.width, dimension.height);
}
revalidate(); //calc bounds
restorePopup();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (myModel.hasChildren(object)) {
restorePopup();
}
else {
doubleClick(object);
}
}
});
}
private void rightClick(final int index) {
final ActionManager actionManager = ActionManager.getInstance();
final ActionGroup group = (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_NAVBAR_POPUP);
final ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.NAVIGATION_BAR, group);
final MyCompositeLabel item = getItem(index);
final MyItemLabel item = getItem(index);
if (item != null) {
popupMenu.getComponent().show(this, item.getX(), item.getY() + item.getHeight());
}
@@ -679,14 +580,6 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
}
public Dimension getPreferredSize() {
return new JButton("1").getPreferredSize();
}
protected int getPreferredWidth() {
return myPreferredWidth + 2 * LEFT_ICON.getIconWidth();
}
@Nullable
public Object getData(String dataId) {
if (dataId.equals(DataConstants.PROJECT)) {
@@ -758,7 +651,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
index = modelSize - 1;
}
if (index > -1 && index < modelSize) {
final MyCompositeLabel item = getItem(index);
final MyItemLabel item = getItem(index);
if (item != null) {
return new Point(item.getX(), item.getY() + item.getHeight());
}
@@ -768,23 +661,53 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
// ----- inplace NavBar -----------
public void installListeners() {
myConnection = myProject.getMessageBus().connect();
final MyPsiTreeChangeAdapter psiListener = new MyPsiTreeChangeAdapter();
final MyProblemListener problemListener = new MyProblemListener();
final MyFileStatusListener fileStatusListener = new MyFileStatusListener();
final MyTimerListener timerListener = new MyTimerListener();
PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeAdapter);
myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new MyModuleRootListener());
WolfTheProblemSolver.getInstance(myProject).addProblemListener(myProblemListener);
FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener);
PsiManager.getInstance(myProject).addPsiTreeChangeListener(psiListener);
WolfTheProblemSolver.getInstance(myProject).addProblemListener(problemListener);
FileStatusManager.getInstance(myProject).addFileStatusListener(fileStatusListener);
final ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
actionManager.addTimerListener(10000, timerListener);
final MessageBusConnection busConnection = myProject.getMessageBus().connect();
busConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new MyModuleRootListener());
busConnection.subscribe(NavBarModelListener.NAV_BAR, new NavBarModelListener() {
public void modelChanged() {
scheduleListUpdate();
}
public void selectionChanged() {
updateItems();
scrollSelectionToVisible();
}
});
if (myDetacher != null) uninstallListeners();
myDetacher = new Runnable() {
public void run() {
ActionManagerEx.getInstanceEx().removeTimerListener(timerListener);
busConnection.disconnect();
WolfTheProblemSolver.getInstance(myProject).removeProblemListener(problemListener);
PsiManager.getInstance(myProject).removePsiTreeChangeListener(psiListener);
FileStatusManager.getInstance(myProject).removeFileStatusListener(fileStatusListener);
}
};
}
public void uninstallListeners() {
if (myConnection != null) {
myConnection.disconnect();
}
myDetacher.run();
myDetacher = null;
WolfTheProblemSolver.getInstance(myProject).removeProblemListener(myProblemListener);
PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeAdapter);
FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener);
myUpdateAlarm.cancelAllRequests();
myListUpdateAlarm.cancelAllRequests();
myModelUpdateAlarm.cancelAllRequests();
}
public void installBorder(final int rightOffset) {
@@ -805,7 +728,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
public Insets getBorderInsets(final Component c) {
return new Insets(1, 1, 1, 1);
return new Insets(4, 4, 4, 4);
}
public boolean isBorderOpaque() {
@@ -816,20 +739,20 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
public void addNotify() {
super.addNotify();
final ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
myWeakTimerListener = new WeakTimerListener(actionManager, myTimerListener);
actionManager.addTimerListener(10000, myWeakTimerListener);
installListeners();
}
public void removeNotify() {
super.removeNotify();
ActionManagerEx.getInstanceEx().removeTimerListener(myWeakTimerListener);
uninstallListeners();
}
public void updateState(final boolean show) {
updateModel();
updateList();
final int selectedIndex = myModel.getSelectedIndex();
if (show && selectedIndex > -1 && selectedIndex < myModel.size()) {
final MyCompositeLabel item = getItem(selectedIndex);
final MyItemLabel item = getItem(selectedIndex);
if (item != null) {
IdeFocusManager.getInstance(myProject).requestFocus(item, true);
}
@@ -838,7 +761,8 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
// ------ popup NavBar ----------
public void showHint(@Nullable final Editor editor, final DataContext dataContext) {
updateList();
updateModel();
if (myModel.isEmpty()) return;
myHint = new LightweightHint(this) {
public void hide() {
@@ -893,95 +817,52 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
});
}
protected static class MyCompositeLabel extends JPanel implements Observer {
private final JLabel myLabel;
private final SimpleColoredComponent myColoredComponent;
@Override
public void paint(Graphics g) {
super.paint(g);
}
protected class MyItemLabel extends SimpleColoredComponent {
private final String myText;
private final SimpleTextAttributes myAttributes;
private final int myIndex;
private int myLastSelectedIndex = -1;
private final Icon myIcon;
private final NavBarModel myModel;
public MyCompositeLabel(final int idx, final Icon icon, @NotNull final String presentableText, final SimpleTextAttributes textAttributes, NavBarModel model) {
super(new GridBagLayout());
myModel = model;
public MyItemLabel(int idx, Icon icon, String presentableText, SimpleTextAttributes textAttributes) {
myIndex = idx;
myText = presentableText;
myIcon = icon;
myAttributes = textAttributes;
final GridBagConstraints gc = new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 0, 0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0);
setFont(UIUtil.getLabelFont());
setBackground(UIUtil.getListBackground());
setOpaque(true);
myLabel = new JLabel(icon);
myLabel.setOpaque(false);
add(myLabel, gc);
myColoredComponent = new SimpleColoredComponent() {
{
setPaintFocusBorder(true);
setFocusBorderAroundIcon(true);
setOpaque(true);
}
};
myColoredComponent.setIpad(new Insets(0, -1, 0, -1));
myColoredComponent.append(presentableText, textAttributes);
myColoredComponent.setOpaque(true);
add(myColoredComponent, gc);
setIpad(new Insets(0, 2, 0, 2));
update();
}
public JLabel getLabel() {
return myLabel;
}
public SimpleColoredComponent getColoredComponent() {
return myColoredComponent;
}
@Override
public void addNotify() {
super.addNotify();
myModel.addSelectionObserver(this);
}
@Override
public void removeNotify() {
super.removeNotify();
myModel.removeSelectionObserver(this);
}
public void update(final Observable o, final Object arg) {
if (myLastSelectedIndex != myModel.getSelectedIndex()) {
update();
myLastSelectedIndex = myModel.getSelectedIndex();
}
}
private void update() {
final Runnable updateRunnable = new Runnable() {
public void run() {
myColoredComponent.clear();
final boolean selected = myModel.getSelectedIndex() == myIndex;
final Color fg = selected
? UIUtil.getListSelectionForeground()
: myModel.getSelectedIndex() < myIndex && myModel.getSelectedIndex() != -1
? UIUtil.getInactiveTextColor()
: myAttributes.getFgColor();
final Color bg = selected ? UIUtil.getListSelectionBackground() : myAttributes.getBgColor();
myColoredComponent.append(myText, new SimpleTextAttributes(bg, fg, myAttributes.getWaveColor(), myAttributes.getStyle()));
if (selected || (myModel.getSelectedIndex() == -1 && myIndex == myModel.size() - 1)) {
myColoredComponent.setBorder(new DottedBorder(new Insets(0, 0, 0, 0), UIUtil.getListForeground()));
}
else {
myColoredComponent.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
}
};
SwingUtilities.invokeLater(updateRunnable);
clear();
setIcon(myIcon);
boolean focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == NavBarPanel.this;
boolean selected = myModel.getSelectedIndex() == myIndex;
setPaintFocusBorder(selected);
setFocusBorderAroundIcon(selected);
setBackground(selected && focused ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground());
final Color fg = selected && focused
? UIUtil.getListSelectionForeground()
: myModel.getSelectedIndex() < myIndex && myModel.getSelectedIndex() != -1
? UIUtil.getInactiveTextColor()
: myAttributes.getFgColor();
final Color bg = selected && focused ? UIUtil.getListSelectionBackground() : myAttributes.getBgColor();
append(myText, new SimpleTextAttributes(bg, fg, myAttributes.getWaveColor(), myAttributes.getStyle()));
repaint();
}
}
@@ -1007,7 +888,9 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
}
updateList();
if (isNodePopupShowing()) return;
scheduleModelUpdate();
}
}
@@ -1016,7 +899,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
public void selectElement(PsiElement element) {
myModel.updateModel(element);
immediateUpdateList(true);
if (element instanceof Navigatable) {
final Navigatable navigatable = (Navigatable)element;
if (navigatable.canNavigate()) {
@@ -1065,49 +948,35 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
private void updateListLater() {
myUpdateAlarm.cancelAllRequests();
myUpdateAlarm.addRequest(new Runnable() {
private void scheduleListUpdate() {
myListUpdateAlarm.cancelAllRequests();
myListUpdateAlarm.addRequest(new Runnable() {
public void run() {
if (myProject.isDisposed()) return;
immediateUpdateList(true);
//rebuildComponent();
updateList();
}
}, 500);
}, 50);
}
private class MyPsiTreeChangeAdapter extends PsiTreeChangeAdapter {
public void childAdded(PsiTreeChangeEvent event) {
updateListLater();
}
public void beforeChildRemoval(final PsiTreeChangeEvent event) {
myUpdateAlarm.cancelAllRequests();
myUpdateAlarm.addRequest(new Runnable() {
public void run() {
if (myProject.isDisposed()) return;
immediateUpdateList(myModel.updateModel(event.getParent()));
}
}, 500);
scheduleModelUpdate();
}
public void childReplaced(PsiTreeChangeEvent event) {
updateListLater();
scheduleModelUpdate();
}
public void childMoved(PsiTreeChangeEvent event) {
updateListLater();
scheduleModelUpdate();
}
public void childrenChanged(PsiTreeChangeEvent event) {
updateListLater();
scheduleModelUpdate();
}
public void propertyChanged(final PsiTreeChangeEvent event) {
final String propertyName = event.getPropertyName();
if (propertyName.equals(PsiTreeChangeEvent.PROP_FILE_NAME) || propertyName.equals(PsiTreeChangeEvent.PROP_DIRECTORY_NAME)) {
updateListLater();
}
scheduleModelUpdate();
}
}
@@ -1116,18 +985,18 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
}
public void rootsChanged(ModuleRootEvent event) {
updateListLater();
scheduleModelUpdate();
}
}
private class MyProblemListener extends WolfTheProblemSolver.ProblemListener {
public void problemsAppeared(VirtualFile file) {
updateListLater();
scheduleListUpdate();
}
public void problemsDisappeared(VirtualFile file) {
updateListLater();
scheduleListUpdate();
}
}
@@ -1135,11 +1004,11 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner {
private class MyFileStatusListener implements FileStatusListener {
public void fileStatusesChanged() {
updateListLater();
scheduleListUpdate();
}
public void fileStatusChanged(@NotNull VirtualFile virtualFile) {
updateListLater();
scheduleListUpdate();
}
}
@@ -8,7 +8,6 @@ import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.wm.impl.IdeRootPaneNorthExtension;
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
@@ -16,89 +15,56 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
private static final Icon CROSS_ICON = IconLoader.getIcon("/actions/cross.png");
private NavBarPanel myNavigationBar;
private JLabel myCloseNavBarLabel;
private JComponent myPanel;
@NonNls public static final String NAV_BAR = "NavBar";
private final Project myProject;
private NavBarPanel myNavigationBar;
public void installComponent(final Project project, final JPanel northPanel) {
if (myNavigationBar == null) {
myNavigationBar = new NavBarPanel(project);
final int iconWidth = CROSS_ICON.getIconWidth();
final int iconHeight = CROSS_ICON.getIconHeight();
myNavigationBar.installBorder(2 * iconWidth + 2);
northPanel.add(myNavigationBar, new GridBagConstraints(0, 1, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
myCloseNavBarLabel = new JLabel(new Icon() {
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
final GraphicsConfig config = new GraphicsConfig(g);
config.setAntialiasing(true);
public NavBarRootPaneExtension(Project project) {
myProject = project;
}
Graphics2D g2d = (Graphics2D)g;
public JComponent getComponent() {
if (myPanel == null) {
myPanel = new JPanel(new BorderLayout());
final GeneralPath path = new GeneralPath();
myPanel.setBackground(UIUtil.getListBackground());
myNavigationBar = new NavBarPanel(myProject);
path.moveTo(-2, iconHeight + 1);
path.curveTo(2 * iconWidth/3, 2 * iconHeight/3, iconWidth/3, iconHeight/3, iconWidth, 0);
path.lineTo(2 * iconWidth, 0);
path.lineTo(2 * iconWidth, iconHeight);
path.lineTo(0, iconHeight);
path.closePath();
JScrollPane scroller = new JScrollPane(myNavigationBar);
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scroller.setHorizontalScrollBar(null);
scroller.setBorder(null);
g2d.setPaint(UIUtil.getListBackground());
g2d.fill(path);
myPanel.add(scroller, BorderLayout.CENTER);
g2d.setPaint(myCloseNavBarLabel.getBackground().darker());
g2d.draw(path);
JLabel closeLabel = new JLabel(CROSS_ICON);
CROSS_ICON.paintIcon(c, g, x + iconWidth - 2, y + 1);
config.restore();
}
public int getIconWidth() {
return 2 * iconWidth;
}
public int getIconHeight() {
return iconHeight;
}
});
myCloseNavBarLabel.addMouseListener(new MouseAdapter() {
closeLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
uiSettingsChanged(UISettings.getInstance());
}
});
northPanel.add(myCloseNavBarLabel, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.SOUTHEAST, GridBagConstraints.NONE,
new Insets(0, 0, 0, 0), 0, 0));
}
}
myPanel.add(closeLabel, BorderLayout.EAST);
public void deinstallComponent(final JPanel northPanel) {
if (myNavigationBar != null) {
northPanel.remove(myNavigationBar);
northPanel.remove(myCloseNavBarLabel);
myPanel.putClientProperty("NavBarPanel", myNavigationBar);
myNavigationBar.installBorder(0);
myPanel.setBorder(myNavigationBar.getBorder());
myNavigationBar.setBorder(null);
}
}
public JComponent getComponent() {
return myNavigationBar;
return myPanel;
}
public void uiSettingsChanged(final UISettings settings) {
if (myNavigationBar != null) {
if (settings.SHOW_NAVIGATION_BAR){
myNavigationBar.installListeners();
} else {
myNavigationBar.uninstallListeners();
}
myNavigationBar.updateState(settings.SHOW_NAVIGATION_BAR);
myNavigationBar.setVisible(settings.SHOW_NAVIGATION_BAR);
myCloseNavBarLabel.setVisible(settings.SHOW_NAVIGATION_BAR);
myPanel.setVisible(settings.SHOW_NAVIGATION_BAR);
}
}
@@ -108,9 +74,8 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
}
public void dispose() {
if (myNavigationBar != null) {
myNavigationBar.uninstallListeners();
}
myPanel.setVisible(false);
myPanel = null;
myNavigationBar = null;
}
}
}
@@ -9,8 +9,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import java.awt.*;
/**
* User: anna
* Date: 19-Dec-2005
@@ -28,12 +26,7 @@ public class PopupToolbarAction extends AnAction implements DumbAware {
return;
}
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
final NavBarPanel toolbarPanel = new NavBarPanel(project) {
public Dimension getPreferredSize() {
final Dimension dimension = super.getPreferredSize();
return new Dimension(getPreferredWidth(), dimension.height);
}
};
final NavBarPanel toolbarPanel = new NavBarPanel(project);
toolbarPanel.showHint(editor, dataContext);
}
@@ -29,6 +29,8 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
/**
* User: anna
* Date: 09-Nov-2005
@@ -61,7 +63,15 @@ public class SelectInNavBarTarget extends SelectInTargetPsiWrapper implements Du
protected void select(final Object selector, VirtualFile virtualFile, final boolean requestFocus) {
final IdeFrameImpl frame = WindowManagerEx.getInstanceEx().getFrame(myProject);
((NavBarPanel)((IdeRootPane)frame.getRootPane()).findByName(NavBarRootPaneExtension.NAV_BAR).getComponent()).select();
navBar(frame).select();
}
private static NavBarPanel navBar(IdeFrameImpl frame) {
return ((NavBarPanel)navBarComponent(frame).getClientProperty("NavBarPanel"));
}
private static JComponent navBarComponent(IdeFrameImpl frame) {
return ((IdeRootPane)frame.getRootPane()).findByName(NavBarRootPaneExtension.NAV_BAR).getComponent();
}
protected boolean canWorkWithCustomObjects() {
@@ -70,7 +80,7 @@ public class SelectInNavBarTarget extends SelectInTargetPsiWrapper implements Du
protected void select(PsiElement element, boolean requestFocus) {
final IdeFrameImpl frame = WindowManagerEx.getInstanceEx().getFrame(myProject);
((NavBarPanel)((IdeRootPane)frame.getRootPane()).findByName(NavBarRootPaneExtension.NAV_BAR).getComponent()).select();
navBar(frame).select();
}
}
@@ -45,7 +45,7 @@ public class IdeRootPane extends JRootPane{
private JComponent myToolbar;
private StatusBarImpl myStatusBar;
private final JPanel myNorthPanel = new JPanel(new GridBagLayout());
private final Box myNorthPanel = Box.createVerticalBox();
private final List<IdeRootPaneNorthExtension> myNorthComponents = new ArrayList<IdeRootPaneNorthExtension>();
/**
@@ -163,7 +163,7 @@ public class IdeRootPane extends JRootPane{
myNorthPanel.remove(myToolbar);
}
myToolbar = createToolbar();
myNorthPanel.add(myToolbar, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0,0));
myNorthPanel.add(myToolbar);
updateToolbarVisibility();
myContentPane.revalidate();
}
@@ -210,14 +210,14 @@ public class IdeRootPane extends JRootPane{
public void installNorthComponents(final Project project) {
myNorthComponents.addAll(Arrays.asList(Extensions.getExtensions(IdeRootPaneNorthExtension.EP_NAME, project)));
for (IdeRootPaneNorthExtension northComponent : myNorthComponents) {
northComponent.installComponent(project, myNorthPanel);
myNorthPanel.add(northComponent.getComponent());
northComponent.uiSettingsChanged(myUISettings);
}
}
public void deinstallNorthComponents(){
for (IdeRootPaneNorthExtension northComponent : myNorthComponents) {
northComponent.deinstallComponent(myNorthPanel);
myNorthPanel.remove(northComponent.getComponent());
Disposer.dispose(northComponent);
}
myNorthComponents.clear();
@@ -7,7 +7,6 @@ package com.intellij.openapi.wm.impl;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import javax.swing.*;
@@ -16,13 +15,7 @@ public abstract class IdeRootPaneNorthExtension implements Disposable {
public abstract String getKey();
public abstract void installComponent(Project project, final JPanel northPanel);
public void deinstallComponent(JPanel northPanel) {
northPanel.remove(getComponent());
}
public abstract JComponent getComponent();
public abstract void uiSettingsChanged(UISettings settings);
}
}