From 1accf9350c7eaaad8efbcd2e2220ebbc3cb12a55 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 27 Nov 2009 18:38:31 +0300 Subject: [PATCH] - make MarkObject dialog appear faster - fix selection clearing after object was marked/unmarked --- .../debugger/actions/MarkObjectAction.java | 101 +++++++++++---------- .../actions/ObjectMarkupPropertiesDialog.java | 21 ++--- .../debugger/ui/impl/FrameDebuggerTree.java | 21 ++++- 3 files changed, 79 insertions(+), 64 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java index 9e7fbcd4f7..d7f4e3a688 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/MarkObjectAction.java @@ -16,6 +16,7 @@ package com.intellij.debugger.actions; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; @@ -78,21 +79,13 @@ public class MarkObjectAction extends DebuggerAction { valueDescriptor.setMarkup(debugProcess, null); } else { - final Value value = valueDescriptor.getValue(); - final Map additionalMarkup = suggestMarkup(debugProcess, value); - ValueMarkup valueMarkup = null; - if (value instanceof ObjectReference) { - valueMarkup = additionalMarkup.get(((ObjectReference)value).uniqueID()); - } - if (valueMarkup == null) { - valueMarkup = new ValueMarkup(valueDescriptor.getName(), Color.RED); - } + final ValueMarkup suggestedMarkup = new ValueMarkup(valueDescriptor.getName(), Color.RED); final Ref> result = new Ref>(null); try { - final ValueMarkup _suggestion = valueMarkup; + final boolean suggestAdditionalMarkup = canSuggestAdditionalMarkup(debugProcess, valueDescriptor.getValue()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { - result.set(ObjectMarkupPropertiesDialog.chooseMarkup(_suggestion, additionalMarkup)); + result.set(ObjectMarkupPropertiesDialog.chooseMarkup(suggestedMarkup, suggestAdditionalMarkup)); } }); } @@ -105,12 +98,16 @@ public class MarkObjectAction extends DebuggerAction { if (pair != null) { valueDescriptor.setMarkup(debugProcess, pair.first); if (pair.second) { - final Map map = NodeDescriptorImpl.getMarkupMap(debugProcess); - if (map != null) { - for (Map.Entry entry : additionalMarkup.entrySet()) { - final Long key = entry.getKey(); - if (!map.containsKey(key)) { - map.put(key, entry.getValue()); + final Value value = valueDescriptor.getValue(); + final Map additionalMarkup = suggestMarkup((ObjectReference)value); + if (!additionalMarkup.isEmpty()) { + final Map map = NodeDescriptorImpl.getMarkupMap(debugProcess); + if (map != null) { + for (Map.Entry entry : additionalMarkup.entrySet()) { + final Long key = entry.getKey(); + if (!map.containsKey(key)) { + map.put(key, entry.getValue()); + } } } } @@ -140,48 +137,56 @@ public class MarkObjectAction extends DebuggerAction { }); } - private static Map suggestMarkup(DebugProcessImpl debugProcess, Value value) { + private static boolean canSuggestAdditionalMarkup(DebugProcessImpl debugProcess, Value value) { + if (!debugProcess.getVirtualMachineProxy().canGetInstanceInfo()) { + return false; + } if (!(value instanceof ObjectReference)) { - return Collections.emptyMap(); + return false; } final ObjectReference objRef = (ObjectReference)value; if (objRef instanceof ArrayReference || objRef instanceof ClassObjectReference || objRef instanceof ThreadReference || objRef instanceof ThreadGroupReference || objRef instanceof ClassLoaderReference) { - return Collections.emptyMap(); + return false; } + return true; + } + + private static Map suggestMarkup(ObjectReference objRef) { final Map result = new HashMap(); - if (debugProcess.getVirtualMachineProxy().canGetInstanceInfo()) { - for (ObjectReference ref : getReferringObjects(objRef)) { - if (!(ref instanceof ClassObjectReference)) { - // consider references from statisc fields only + for (ObjectReference ref : getReferringObjects(objRef)) { + if (!(ref instanceof ClassObjectReference)) { + // consider references from statisc fields only + continue; + } + final ReferenceType refType = ((ClassObjectReference)ref).reflectedType(); + if (!refType.isAbstract()) { + continue; + } + for (Field field : refType.visibleFields()) { + if (!(field.isStatic() && field.isFinal())) { continue; } - final ReferenceType refType = ((ClassObjectReference)ref).reflectedType(); - if (!refType.isAbstract()) { + if (DebuggerUtils.isPrimitiveType(field.typeName())) { continue; } - for (Field field : refType.fields()) { - if (!(field.isStatic() && field.isFinal())) { - continue; - } - final Value fieldValue = refType.getValue(field); - if (!(fieldValue instanceof ObjectReference)) { - continue; - } - final long id = ((ObjectReference)fieldValue).uniqueID(); - final ValueMarkup markup = result.get(id); + final Value fieldValue = refType.getValue(field); + if (!(fieldValue instanceof ObjectReference)) { + continue; + } + final long id = ((ObjectReference)fieldValue).uniqueID(); + final ValueMarkup markup = result.get(id); - final String fieldName = field.name(); - final Color autoMarkupColor = ValueMarkup.getAutoMarkupColor(); - if (markup == null) { - result.put(id, new ValueMarkup(fieldName, autoMarkupColor, createMarkupTooltipText(null, refType, fieldName))); - } - else { - final String currentText = markup.getText(); - if (!currentText.contains(fieldName)) { - final String currentTooltip = markup.getToolTipText(); - final String tooltip = createMarkupTooltipText(currentTooltip, refType, fieldName); - result.put(id, new ValueMarkup(currentText + ", " + fieldName, autoMarkupColor, tooltip)); - } + final String fieldName = field.name(); + final Color autoMarkupColor = ValueMarkup.getAutoMarkupColor(); + if (markup == null) { + result.put(id, new ValueMarkup(fieldName, autoMarkupColor, createMarkupTooltipText(null, refType, fieldName))); + } + else { + final String currentText = markup.getText(); + if (!currentText.contains(fieldName)) { + final String currentTooltip = markup.getToolTipText(); + final String tooltip = createMarkupTooltipText(currentTooltip, refType, fieldName); + result.put(id, new ValueMarkup(currentText + ", " + fieldName, autoMarkupColor, tooltip)); } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java index f416dacb65..7182194109 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java @@ -35,7 +35,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import java.util.Map; /** * @author Eugene Zhuravlev @@ -48,16 +47,16 @@ public class ObjectMarkupPropertiesDialog extends DialogWrapper { private SimpleTextAttributes myAttributes; private final Alarm myUpdateAlarm; private static final int UPDATE_DELAY = 200; - private final Map myAdditional; private static Boolean ourMarkCbSavedState; + private final boolean mySuggestAdditionalMarkup; - public ObjectMarkupPropertiesDialog(@NotNull final ValueMarkup suggestion, @NotNull Map additional) { + public ObjectMarkupPropertiesDialog(@NotNull final ValueMarkup suggestion, boolean suggestAdditionalMarkup) { super(true); - myAdditional = additional; + mySuggestAdditionalMarkup = suggestAdditionalMarkup; setTitle("Select object label"); setModal(true); myTextMarkupField = new JTextField(30); - myCbMarkAdditionalFields = new JCheckBox("Mark values referenced from constant fields", ourMarkCbSavedState == null? additional.size() > 0 : ourMarkCbSavedState); + myCbMarkAdditionalFields = new JCheckBox("Mark values referenced from constant fields", ourMarkCbSavedState == null? suggestAdditionalMarkup : ourMarkCbSavedState); myCbMarkAdditionalFields.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { ourMarkCbSavedState = myCbMarkAdditionalFields.isSelected(); @@ -96,18 +95,18 @@ public class ObjectMarkupPropertiesDialog extends DialogWrapper { samplePanel.setBorder(BorderFactory.createEtchedBorder()); final FixedSizeButton chooseColorButton = new FixedSizeButton(samplePanel); - final boolean shouldShowCheckbox = myAdditional.size() > 0; - double weighty = shouldShowCheckbox? 0.0 : 1.0; + double weighty = mySuggestAdditionalMarkup ? 0.0 : 1.0; mainPanel.add(new JLabel("Preview: "), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0)); mainPanel.add(samplePanel, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 0), 0, 0)); mainPanel.add(chooseColorButton, new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0)); - if (shouldShowCheckbox) { + if (mySuggestAdditionalMarkup) { final JPanel panel = new JPanel(new BorderLayout()); panel.add(new MultiLineLabel( - "The value is referenced by a constant field of an abstract class.\nIDEA could mark values referenced from this class with the names of referencing fields." + "If the value is referenced by a constant field of an abstract class,\nIDEA could additionally mark all values referenced from this class with the names of referencing fields." ), BorderLayout.CENTER); panel.add(myCbMarkAdditionalFields, BorderLayout.SOUTH); + myCbMarkAdditionalFields.setMnemonic('M'); mainPanel.add(panel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0)); } @@ -138,8 +137,8 @@ public class ObjectMarkupPropertiesDialog extends DialogWrapper { }, updateDelay); } - public static Pair chooseMarkup(ValueMarkup suggestion, Map additionalMarkup) { - final ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(suggestion, additionalMarkup); + public static Pair chooseMarkup(ValueMarkup suggestion, boolean suggestAdditionalMarkup) { + final ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(suggestion, suggestAdditionalMarkup); dialog.show(); if (dialog.isOK()) { final String text = dialog.myTextMarkupField.getText().trim(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameDebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameDebuggerTree.java index 79ee2da471..16f0f01e87 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameDebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameDebuggerTree.java @@ -400,6 +400,9 @@ public class FrameDebuggerTree extends DebuggerTree { private void autoscrollToNewLocals(DebuggerTreeNodeImpl frameNode) { final DebuggerSession debuggerSession = debuggerContext.getDebuggerSession(); final boolean isSteppingThrough = debuggerSession.isSteppingThrough(debuggerContext.getThreadProxy()); + final List toClear = new ArrayList(); + final List newLocalsToSelect = new ArrayList(); + for (Enumeration e = frameNode.rawChildren(); e.hasMoreElements();) { final DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)e.nextElement(); final NodeDescriptorImpl descriptor = child.getDescriptor(); @@ -408,17 +411,25 @@ public class FrameDebuggerTree extends DebuggerTree { } final LocalVariableDescriptorImpl localVariableDescriptor = (LocalVariableDescriptorImpl)descriptor; if (isSteppingThrough && localVariableDescriptor.isNewLocal()) { - TreePath treePath = new TreePath(child.getPath()); - addSelectionPath(treePath); myAnyNewLocals = true; - descriptor.myIsSelected = true; + newLocalsToSelect.add(child); } else { - removeSelectionPath(new TreePath(child.getPath())); - descriptor.myIsSelected = false; + toClear.add(child); } localVariableDescriptor.setNewLocal(false); } + + if (!newLocalsToSelect.isEmpty()) { + for (DebuggerTreeNodeImpl child : toClear) { + removeSelectionPath(new TreePath(child.getPath())); + child.getDescriptor().myIsSelected = false; + } + for (DebuggerTreeNodeImpl child : newLocalsToSelect) { + addSelectionPath(new TreePath(child.getPath())); + child.getDescriptor().myIsSelected = true; + } + } } }); } -- 2.11.4.GIT