breakpoints ui. breakpoints list updating with adding/removing breakpoints.

This commit is contained in:
andrey.zaytsev
2012-05-15 17:51:37 +04:00
parent 42efc41fa1
commit 6d3f269f1b
16 changed files with 234 additions and 35 deletions
@@ -49,6 +49,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author nik
@@ -185,6 +186,8 @@ public class JavaDebuggerSupport extends DebuggerSupport {
}
private static class JavaBreakpointPanelProvider extends BreakpointPanelProvider<Breakpoint> {
private List<MyBreakpointManagerListener> myListeners = new CopyOnWriteArrayList<MyBreakpointManagerListener>();
@NotNull
public Collection<AbstractBreakpointPanel<Breakpoint>> getBreakpointPanels(@NotNull final Project project, @NotNull final DialogWrapper parentDialog) {
List<AbstractBreakpointPanel<Breakpoint>> panels = new ArrayList<AbstractBreakpointPanel<Breakpoint>>();
@@ -209,6 +212,23 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return result.toArray(new AnAction[result.size()]);
}
@Override
public void addListener(final BreakpointsListener listener, Project project) {
final MyBreakpointManagerListener listener1 = new MyBreakpointManagerListener(listener);
DebuggerManagerEx.getInstanceEx(getCurrentProject()).getBreakpointManager().addBreakpointManagerListener(listener1);
myListeners.add(listener1);
}
@Override
public void removeListener(BreakpointsListener listener) {
for (MyBreakpointManagerListener managerListener : myListeners) {
if (managerListener.myListener == listener) {
myListeners.remove(managerListener);
break;
}
}
}
public int getPriority() {
return 1;
}
@@ -264,6 +284,20 @@ public class JavaDebuggerSupport extends DebuggerSupport {
myBreakpointFactory.addBreakpoint(getEventProject(e));
}
}
private static class MyBreakpointManagerListener implements BreakpointManagerListener {
private final BreakpointsListener myListener;
public MyBreakpointManagerListener(BreakpointsListener listener) {
myListener = listener;
}
@Override
public void breakpointsChanged() {
myListener.breakpointsChanged();
}
}
}
public static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider {
@@ -62,6 +62,11 @@ public class AnyExceptionBreakpointFactory extends BreakpointFactory{
return new BreakpointPanelAction[0]; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean breakpointCanBeRemoved(Breakpoint breakpoint) {
return false;
}
public @Nullable BreakpointPanel createBreakpointPanel(Project project, DialogWrapper parentDialog) {
return null;
}
@@ -16,7 +16,6 @@
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.ui.breakpoints.actions.BreakpointPanelAction;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
@@ -87,6 +86,10 @@ public abstract class BreakpointFactory {
return false;
}
public boolean breakpointCanBeRemoved(Breakpoint breakpoint) {
return true;
}
public BreakpointItem createBreakpointItem(final Breakpoint breakpoint) {
return new JavaBreakpointItem(this, breakpoint);
}
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.SourcePosition;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.project.Project;
@@ -69,8 +70,8 @@ class JavaBreakpointItem implements BreakpointItem {
@Override
public void updateDetailView(DetailView panel) {
if (myBreakpoint instanceof LineBreakpoint) {
SourcePosition sourcePosition = ((LineBreakpoint)myBreakpoint).getSourcePosition();
if (myBreakpoint instanceof BreakpointWithHighlighter) {
SourcePosition sourcePosition = ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition();
VirtualFile virtualFile = sourcePosition.getFile().getVirtualFile();
panel.navigateInPreviewEditor(virtualFile, new LogicalPosition(sourcePosition.getLine(), 0));
}
@@ -82,15 +83,28 @@ class JavaBreakpointItem implements BreakpointItem {
final JPanel mainPanel = breakpointPropertiesPanel.getPanel();
panel.setDetailPanel(mainPanel);
}
else {
panel.setDetailPanel(null);
}
}
@Override
public boolean allowedToRemove() {
return false; //To change body of implemented methods use File | Settings | File Templates.
return myBreakpointFactory.breakpointCanBeRemoved(myBreakpoint);
}
@Override
public void removed(Project project) {
DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().removeBreakpoint(myBreakpoint);
}
@Override
public Object getBreakpoint() {
return myBreakpoint;
}
@Override
public int getPriority() {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
}
@@ -18,6 +18,7 @@ package com.intellij.ui.popup.util;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -37,5 +38,5 @@ public interface DetailView {
JPanel getDetailPanel();
void setDetailPanel(JPanel panel);
void setDetailPanel(@Nullable JPanel panel);
}
@@ -42,4 +42,6 @@ public interface ItemWrapper {
void updateDetailView(DetailView panel);
boolean allowedToRemove();
void removed(Project project);
}
@@ -19,9 +19,6 @@ import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.ui.popup.util.DetailViewImpl;
import com.intellij.ui.popup.util.ItemWrapper;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusManager;
@@ -32,6 +29,8 @@ import com.intellij.psi.PsiManager;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.FileColorManager;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.ui.popup.util.ItemWrapper;
import javax.swing.*;
import java.awt.*;
@@ -123,4 +122,9 @@ public class BookmarkItem implements ItemWrapper {
public boolean allowedToRemove() {
return true;
}
@Override
public void removed(Project project) {
BookmarkManager.getInstance(project).removeBookmark(getBookmark());
}
}
@@ -133,6 +133,8 @@ public class DetailViewImpl extends JPanel implements DetailView {
remove(myDetailPanel);
}
myDetailPanel = panel;
add(panel, BorderLayout.SOUTH);
if (panel != null) {
add(panel, BorderLayout.SOUTH);
}
}
}
@@ -205,7 +205,7 @@ public class MasterDetailPopupBuilder {
else {
myList.clearSelection();
}
myDelegate.itemRemoved(item, myProject);
item.removed(myProject);
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.xdebugger.breakpoints.ui;
import com.intellij.openapi.util.Key;
import com.intellij.ui.popup.util.ItemWrapper;
/**
@@ -27,4 +26,5 @@ import com.intellij.ui.popup.util.ItemWrapper;
*/
public interface BreakpointItem extends ItemWrapper {
Object getBreakpoint();
int getPriority();
}
@@ -15,6 +15,8 @@
*/
package com.intellij.xdebugger.impl.breakpoints;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.project.Project;
import com.intellij.ui.ColoredListCellRenderer;
@@ -22,7 +24,7 @@ import com.intellij.ui.popup.util.DetailView;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.impl.breakpoints.ui.XBreakpointPropertiesPanel;
import com.intellij.xdebugger.impl.breakpoints.ui.XLightBreakpointPropertiesPanel;
import javax.swing.*;
@@ -43,6 +45,7 @@ class XBreakpointItem implements BreakpointItem {
@Override
public void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected) {
renderer.setIcon(((XBreakpointBase)myBreakpoint).getIcon());
renderer.append(XBreakpointUtil.getDisplayText(myBreakpoint));
}
@Override
@@ -74,19 +77,39 @@ class XBreakpointItem implements BreakpointItem {
Project project = ((XBreakpointBase)myBreakpoint).getProject();
XBreakpointPropertiesPanel<XBreakpoint<?>> propertiesPanel =
new XBreakpointPropertiesPanel<XBreakpoint<?>>(project, ((XBreakpointBase)myBreakpoint).getBreakpointManager(), myBreakpoint);
XLightBreakpointPropertiesPanel<XBreakpoint<?>> propertiesPanel =
new XLightBreakpointPropertiesPanel<XBreakpoint<?>>(project, getManager(), myBreakpoint, true);
panel.setDetailPanel(propertiesPanel.getMainPanel());
}
private XBreakpointManagerImpl getManager() {
return ((XBreakpointBase)myBreakpoint).getBreakpointManager();
}
@Override
public boolean allowedToRemove() {
return false; //To change body of implemented methods use File | Settings | File Templates.
return !getManager().isDefaultBreakpoint(myBreakpoint);
}
@Override
public void removed(Project project) {
final XBreakpointManagerImpl breakpointManager = getManager();
new WriteAction() {
protected void run(final Result result) {
breakpointManager.removeBreakpoint(myBreakpoint);
}
}.execute();
}
@Override
public Object getBreakpoint() {
return myBreakpoint;
}
@Override
public int getPriority() {
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,12 +37,32 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author nik
*/
public class XBreakpointPanelProvider extends BreakpointPanelProvider<XBreakpoint> {
private List<MyXBreakpointListener> myListeners = new CopyOnWriteArrayList<MyXBreakpointListener>();
@Override
public void addListener(BreakpointsListener listener, Project project) {
final MyXBreakpointListener listener1 = new MyXBreakpointListener(listener);
XDebuggerManager.getInstance(project).getBreakpointManager().addBreakpointListener(listener1);
myListeners.add(listener1);
}
@Override
public void removeListener(BreakpointsListener listener) {
for (MyXBreakpointListener breakpointListener : myListeners) {
if (breakpointListener.myListener == listener) {
myListeners.remove(breakpointListener);
break;
}
}
}
public int getPriority() {
return 0;
}
@@ -97,7 +117,7 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider<XBreakpoin
result.add(new AddXBreakpointAction(type));
}
}
return new AnAction[0];
return result.toArray(new AnAction[result.size()]);
}
private static <B extends XBreakpoint<?>> XBreakpointsPanel<B> createBreakpointsPanel(final Project project, DialogWrapper parentDialog, final XBreakpointType<B, ?> type) {
@@ -115,6 +135,28 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider<XBreakpoin
}
}
private static class MyXBreakpointListener implements XBreakpointListener<XBreakpoint<?>> {
public BreakpointsListener myListener;
public MyXBreakpointListener(BreakpointsListener listener) {
myListener = listener;
}
@Override
public void breakpointAdded(@NotNull XBreakpoint<?> breakpoint) {
myListener.breakpointsChanged();
}
@Override
public void breakpointRemoved(@NotNull XBreakpoint<?> breakpoint) {
myListener.breakpointsChanged();
}
@Override
public void breakpointChanged(@NotNull XBreakpoint<?> breakpoint) {
}
}
private class AddXBreakpointAction extends AnAction {
private XBreakpointType<?, ?> myType;
@@ -30,6 +30,15 @@ import java.util.Collection;
* @author nik
*/
public abstract class BreakpointPanelProvider<B> {
public interface BreakpointsListener {
void breakpointsChanged();
}
public abstract void addListener(BreakpointsListener listener, Project project);
public abstract void removeListener(BreakpointsListener listener);
public abstract int getPriority();
@Nullable
@@ -15,7 +15,6 @@
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.ide.actions.ShowPopupMenuAction;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -23,22 +22,22 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.ui.AnActionButton;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.ui.components.JBList;
import com.intellij.ui.popup.util.ItemWrapper;
import com.intellij.ui.popup.util.MasterDetailPopupBuilder;
import com.intellij.util.PlatformIcons;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointListener;
import com.intellij.xdebugger.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.impl.DebuggerSupport;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Created with IntelliJ IDEA.
@@ -60,8 +59,8 @@ public class BreakpointsMasterDetailPopupFactory {
}
Collections.sort(myBreakpointPanelProviders, new Comparator<BreakpointPanelProvider>() {
@Override
public int compare(BreakpointPanelProvider breakpointPanelProvider, BreakpointPanelProvider breakpointPanelProvider1) {
return breakpointPanelProvider.getPriority() - breakpointPanelProvider1.getPriority();
public int compare(BreakpointPanelProvider o1, BreakpointPanelProvider o2) {
return o2.getPriority() - o1.getPriority();
}
});
}
@@ -71,8 +70,10 @@ public class BreakpointsMasterDetailPopupFactory {
}
public JBPopup createPopup(@Nullable Object initialBreakpoint) {
DefaultListModel model = createBreakpointsItemsList();
final DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
final BreakpointListModel model = createBreakpointsItemsList(selectionModel);
final JBList list = new JBList(model);
list.setSelectionModel(selectionModel);
list.getEmptyText().setText("No Bookmarks");
DefaultActionGroup actions = getActions();
@@ -99,9 +100,20 @@ public class BreakpointsMasterDetailPopupFactory {
public boolean hasItemsWithMnemonic(Project project) {
return false;
}
}).createMasterDetailPopup();
popup.addListener(new JBPopupListener() {
@Override
public void beforeShown(LightweightWindowEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void onClosed(LightweightWindowEvent event) {
model.unsubscribe();
}
});
return popup;
}
@@ -124,15 +136,63 @@ public class BreakpointsMasterDetailPopupFactory {
return actions;
}
private DefaultListModel createBreakpointsItemsList() {
DefaultListModel model = new DefaultListModel();
private BreakpointListModel createBreakpointsItemsList(DefaultListSelectionModel selectionModel) {
final BreakpointListModel model = new BreakpointListModel();
final ArrayList<BreakpointItem> items = collectItems();
for (BreakpointItem item : items) {
model.addElement(item);
}
model.subscribe(selectionModel);
return model;
}
private ArrayList<BreakpointItem> collectItems() {
ArrayList<BreakpointItem> items = new ArrayList<BreakpointItem>();
for (BreakpointPanelProvider panelProvider : myBreakpointPanelProviders) {
panelProvider.provideBreakpointItems(myProject, items);
}
for (BreakpointItem item : items) {
model.addElement(item);
return items;
}
private class BreakpointListModel extends DefaultListModel {
List<BreakpointPanelProvider.BreakpointsListener> myListeners = new ArrayList<BreakpointPanelProvider.BreakpointsListener>();
private void subscribe(DefaultListSelectionModel selectionModel) {
for (BreakpointPanelProvider panelProvider : myBreakpointPanelProviders) {
final BreakpointPanelProvider.BreakpointsListener listener = new MyBreakpointsListener(this, selectionModel);
panelProvider.addListener(listener, myProject);
myListeners.add(listener);
}
}
public void unsubscribe() {
for (int i = 0, size = myListeners.size(); i < size; i++) {
BreakpointPanelProvider.BreakpointsListener listener = myListeners.get(i);
myBreakpointPanelProviders.get(i).removeListener(listener);
}
}
}
private class MyBreakpointsListener implements BreakpointPanelProvider.BreakpointsListener {
private final DefaultListModel myModel;
private DefaultListSelectionModel mySelectionModel;
public MyBreakpointsListener(DefaultListModel model, DefaultListSelectionModel selectionModel) {
myModel = model;
mySelectionModel = selectionModel;
}
@Override
public void breakpointsChanged() {
final int index = mySelectionModel.getLeadSelectionIndex();
myModel.removeAllElements();
final ArrayList<BreakpointItem> items = collectItems();
for (BreakpointItem item : items) {
myModel.addElement(item);
}
mySelectionModel.setLeadSelectionIndex(index);
}
return model;
}
}
@@ -158,7 +158,7 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
}
}
public JComponent getMainPanel() {
public JPanel getMainPanel() {
return myMainPanel;
}
}
@@ -268,7 +268,7 @@ public class DebuggerUIUtil {
balloon.showInCenterOf(component);
}
else {
balloon.show(new RelativePoint(component, whereToShow), Balloon.Position.atRight);
balloon.show(new RelativePoint(component, whereToShow), Balloon.Position.below);
}
return balloon;