From b878d04288a2ed538ae5549e1a1d14c9528b7ebb Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 6 Aug 2014 19:27:49 +0400 Subject: [PATCH] reduce debugger views flickering --- .../debugger/ui/impl/VariablesPanel.java | 8 +++++ .../xdebugger/impl/frame/XDebugView.java | 29 +++++++++++++++-- .../xdebugger/impl/frame/XFramesView.java | 32 ++++++++++++------- .../impl/frame/XStandaloneVariablesView.java | 8 +++++ .../xdebugger/impl/frame/XVariablesView.java | 30 ++++++++++------- .../impl/frame/XVariablesViewBase.java | 3 +- .../impl/frame/XWatchesViewImpl.java | 12 +++++-- 7 files changed, 92 insertions(+), 30 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java index 1bda597586e8..ead97cba1c63 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/VariablesPanel.java @@ -147,5 +147,13 @@ public class VariablesPanel extends DebuggerTreePanel implements DataProvider { buildTreeAndRestoreState(stackFrame); } } + + @Override + protected void clear() { + } + + @Override + public void processSessionEvent(@NotNull SessionEvent event) { + } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java index 85ff7b2c2357..dcab8b452b93 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XDebugView.java @@ -16,13 +16,36 @@ package com.intellij.xdebugger.impl.frame; import com.intellij.openapi.Disposable; +import com.intellij.util.SingleAlarm; import org.jetbrains.annotations.NotNull; /** * @author nik */ -public interface XDebugView extends Disposable { - enum SessionEvent {PAUSED, BEFORE_RESUME, RESUMED, STOPPED, FRAME_CHANGED, SETTINGS_CHANGED} +public abstract class XDebugView implements Disposable { + public enum SessionEvent {PAUSED, BEFORE_RESUME, RESUMED, STOPPED, FRAME_CHANGED, SETTINGS_CHANGED} - void processSessionEvent(@NotNull SessionEvent event); + private final SingleAlarm myClearAlarm; + private static final int VIEW_CLEAR_DELAY = 100; //ms + + public XDebugView(Disposable disposable) { + myClearAlarm = new SingleAlarm(new Runnable() { + @Override + public void run() { + clear(); + } + }, VIEW_CLEAR_DELAY, disposable); + } + + protected final void requestClear() { + myClearAlarm.cancelAndRequest(); + } + + protected final void cancelClear() { + myClearAlarm.cancel(); + } + + protected abstract void clear(); + + public abstract void processSessionEvent(@NotNull SessionEvent event); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java index b7c5f4bf9746..134139902278 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java @@ -29,6 +29,7 @@ import com.intellij.ui.border.CustomLineBorder; import com.intellij.ui.components.panels.Wrapper; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.frame.XExecutionStack; import com.intellij.xdebugger.frame.XStackFrame; @@ -53,7 +54,7 @@ import java.util.List; /** * @author nik */ -public class XFramesView implements XDebugView { +public class XFramesView extends XDebugView { private final JPanel myMainPanel; private final XDebuggerFramesList myFramesList; private final ComboBox myThreadComboBox; @@ -65,8 +66,10 @@ public class XFramesView implements XDebugView { private final ActionToolbarImpl myToolbar; private final Wrapper myThreadsPanel; private boolean myThreadsCalculated = false; + private final TransferToEDTQueue myLaterInvocator = TransferToEDTQueue.createRunnableMerger("XFramesView later invocator", 50); public XFramesView(@NotNull final XDebugSession session) { + super(session.getProject()); mySession = session; myMainPanel = new JPanel(new BorderLayout()); @@ -197,14 +200,14 @@ public class XFramesView implements XDebugView { myBuilders.clear(); mySelectedStack = null; XSuspendContext suspendContext = mySession.getSuspendContext(); - if (suspendContext == null || event == SessionEvent.PAUSED) { - myThreadComboBox.removeAllItems(); - myFramesList.clear(); - myThreadsCalculated = false; - myExecutionStacks.clear(); - if (suspendContext == null) { - return; - } + if (suspendContext == null) { + requestClear(); + return; + } + if (event == SessionEvent.PAUSED) { + // clear immediately + cancelClear(); + clear(); } XExecutionStack[] executionStacks = suspendContext.getExecutionStacks(); @@ -223,6 +226,13 @@ public class XFramesView implements XDebugView { myListenersEnabled = true; } + protected void clear() { + myThreadComboBox.removeAllItems(); + myFramesList.clear(); + myThreadsCalculated = false; + myExecutionStacks.clear(); + } + private void addExecutionStacks(List executionStacks) { for (XExecutionStack executionStack : executionStacks) { if (!myExecutionStacks.contains(executionStack)) { @@ -315,7 +325,7 @@ public class XFramesView implements XDebugView { @Override public void addStackFrames(@NotNull final List stackFrames, final boolean last) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + myLaterInvocator.offer(new Runnable() { @Override public void run() { myStackFrames.addAll(stackFrames); @@ -331,7 +341,7 @@ public class XFramesView implements XDebugView { @Override public void errorOccurred(@NotNull final String errorMessage) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + myLaterInvocator.offer(new Runnable() { @Override public void run() { if (myErrorMessage == null) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java index f7f32ba86b9c..f91146426878 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XStandaloneVariablesView.java @@ -42,4 +42,12 @@ public class XStandaloneVariablesView extends XVariablesViewBase { } }); } + + @Override + public void processSessionEvent(@NotNull SessionEvent event) { + } + + @Override + protected void clear() { + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java index 31b30a8362e3..f5393f31cd85 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java @@ -28,7 +28,7 @@ import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createIn /** * @author nik */ -public class XVariablesView extends XVariablesViewBase implements XDebugView { +public class XVariablesView extends XVariablesViewBase { @NotNull private final XDebugSession mySession; public XVariablesView(@NotNull XDebugSession session) { @@ -50,20 +50,26 @@ public class XVariablesView extends XVariablesViewBase implements XDebugView { tree.markNodesObsolete(); if (stackFrame != null) { + cancelClear(); buildTreeAndRestoreState(stackFrame); } else { - tree.setSourcePosition(null); - - XDebuggerTreeNode node; - if (!mySession.isStopped() && mySession.isPaused()) { - node = createInfoMessage(tree, "Frame is not available"); - } - else { - XDebugProcess debugProcess = mySession.getDebugProcess(); - node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener()); - } - tree.setRoot(node, true); + requestClear(); } } + + protected void clear() { + XDebuggerTree tree = getTree(); + tree.setSourcePosition(null); + + XDebuggerTreeNode node; + if (!mySession.isStopped() && mySession.isPaused()) { + node = createInfoMessage(tree, "Frame is not available"); + } + else { + XDebugProcess debugProcess = mySession.getDebugProcess(); + node = createInfoMessage(tree, debugProcess.getCurrentStateMessage(), debugProcess.getCurrentStateHyperlinkListener()); + } + tree.setRoot(node, true); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java index 33a1639ba5d7..30a15ef62060 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java @@ -35,13 +35,14 @@ import javax.swing.*; /** * @author nik */ -public abstract class XVariablesViewBase implements Disposable { +public abstract class XVariablesViewBase extends XDebugView { protected final XDebuggerTreePanel myDebuggerTreePanel; private XDebuggerTreeState myTreeState; private Object myFrameEqualityObject; private XDebuggerTreeRestorer myTreeRestorer; protected XVariablesViewBase(@NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, @Nullable XValueMarkers markers) { + super(project); myDebuggerTreePanel = new XDebuggerTreePanel(project, editorsProvider, this, null, XDebuggerActions.VARIABLES_TREE_POPUP_GROUP, markers); myDebuggerTreePanel.getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.variables.not.available")); DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree()); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java index 6216c1312349..e21b9583b279 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java @@ -64,7 +64,7 @@ import java.util.List; /** * @author nik */ -public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugView { +public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWatchesView { private final XDebuggerTreePanel myTreePanel; private XDebuggerTreeState myTreeState; private XDebuggerTreeRestorer myTreeRestorer; @@ -75,6 +75,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi private boolean myRebuildNeeded; public XWatchesViewImpl(@NotNull final XDebugSessionImpl session) { + super(session.getProject()); mySession = session; myTreePanel = new XDebuggerTreePanel(session.getProject(), session.getDebugProcess().getEditorsProvider(), this, null, XDebuggerActions.WATCHES_TREE_POPUP_GROUP, ((XDebugSessionImpl)session).getValueMarkers()); @@ -269,6 +270,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi } if (stackFrame != null) { + cancelClear(); tree.setSourcePosition(stackFrame.getSourcePosition()); myRootNode.updateWatches(stackFrame.getEvaluator()); if (myTreeState != null) { @@ -276,11 +278,15 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi } } else { - tree.setSourcePosition(null); - myRootNode.updateWatches(null); + requestClear(); } } + protected void clear() { + getTree().setSourcePosition(null); + myRootNode.updateWatches(null); + } + public XDebuggerTree getTree() { return myTreePanel.getTree(); }