diff --git a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/actions/JvmDropFrameActionHandler.java b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/actions/JvmDropFrameActionHandler.java index 524cc8954d..72035b56e9 100644 --- a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/actions/JvmDropFrameActionHandler.java +++ b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/actions/JvmDropFrameActionHandler.java @@ -10,7 +10,6 @@ import com.intellij.java.debugger.localize.JavaDebuggerLocalize; import com.intellij.java.language.psi.*; import consulo.annotation.access.RequiredReadAction; -import consulo.execution.debug.XDebuggerBundle; import consulo.execution.debug.breakpoint.XExpression; import consulo.execution.debug.evaluation.EvaluationMode; import consulo.execution.debug.evaluation.XDebuggerEvaluator; @@ -68,7 +67,7 @@ public void drop(@Nonnull XStackFrame frame) { myDebugSession.setSteppingThrough(stackFrame.getStackFrameProxy().threadProxy()); if (evaluateFinallyBlocks( project, - XDebuggerBundle.message("xdebugger.reset.frame.title"), + XDebuggerLocalize.xdebuggerResetFrameTitle().get(), stackFrame, new XDebuggerEvaluator.XEvaluationCallback() { @Override @@ -81,7 +80,7 @@ public void errorOccurred(@Nonnull String errorMessage) { showError( project, JavaDebuggerLocalize.errorExecutingFinally(errorMessage).get(), - XDebuggerBundle.message("xdebugger.reset.frame.title") + XDebuggerLocalize.xdebuggerResetFrameTitle().get() ); } } @@ -204,7 +203,7 @@ private static void evaluateAndAct( Messages.showMessageDialog( project, XDebuggerLocalize.xdebuggerEvaluateStackFrameHasNotEvaluator().get(), - XDebuggerBundle.message("xdebugger.reset.frame.title"), + XDebuggerLocalize.xdebuggerResetFrameTitle().get(), UIUtil.getErrorIcon() ); } diff --git a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/JavaDebugProcess.java b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/JavaDebugProcess.java index 992f508906..a04d2d3e0d 100644 --- a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/JavaDebugProcess.java +++ b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/engine/JavaDebugProcess.java @@ -15,7 +15,6 @@ */ package com.intellij.java.debugger.impl.engine; -import com.intellij.java.debugger.DebuggerBundle; import com.intellij.java.debugger.engine.evaluation.EvaluationContext; import com.intellij.java.debugger.impl.*; import com.intellij.java.debugger.impl.actions.DebuggerActions; @@ -31,6 +30,7 @@ import com.intellij.java.debugger.impl.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.java.debugger.impl.ui.impl.watch.MessageDescriptor; import com.intellij.java.debugger.impl.ui.impl.watch.NodeManagerImpl; +import com.intellij.java.debugger.localize.JavaDebuggerLocalize; import com.intellij.java.debugger.ui.tree.NodeDescriptor; import consulo.execution.debug.*; import consulo.execution.debug.breakpoint.XBreakpoint; @@ -41,6 +41,7 @@ import consulo.execution.debug.frame.XStackFrame; import consulo.execution.debug.frame.XValueMarkerProvider; import consulo.execution.debug.icon.ExecutionDebugIconGroup; +import consulo.execution.debug.localize.XDebuggerLocalize; import consulo.execution.debug.step.XSmartStepIntoHandler; import consulo.execution.debug.ui.DebuggerContentInfo; import consulo.execution.debug.ui.XDebugTabLayouter; @@ -50,6 +51,7 @@ import consulo.execution.ui.layout.RunnerLayoutUi; import consulo.fileEditor.EditorNotifications; import consulo.internal.com.sun.jdi.event.Event; +import consulo.localize.LocalizeValue; import consulo.process.ProcessHandler; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; @@ -77,19 +79,19 @@ public class JavaDebugProcess extends XDebugProcess { private final JvmDropFrameActionHandler myDropFrameActionActionHandler; private final NodeManagerImpl myNodeManager; - public static JavaDebugProcess create(@Nonnull final XDebugSession session, final DebuggerSession javaSession) { + public static JavaDebugProcess create(@Nonnull XDebugSession session, DebuggerSession javaSession) { JavaDebugProcess res = new JavaDebugProcess(session, javaSession); javaSession.getProcess().setXDebugProcess(res); return res; } - protected JavaDebugProcess(@Nonnull final XDebugSession session, final DebuggerSession javaSession) { + protected JavaDebugProcess(@Nonnull XDebugSession session, DebuggerSession javaSession) { super(session); myJavaSession = javaSession; myEditorsProvider = new JavaDebuggerEditorsProvider(); - final DebugProcessImpl process = javaSession.getProcess(); + DebugProcessImpl process = javaSession.getProcess(); - List handlers = new ArrayList(); + List handlers = new ArrayList<>(); handlers.add(new JavaBreakpointHandler.JavaLineBreakpointHandler(process)); handlers.add(new JavaBreakpointHandler.JavaExceptionBreakpointHandler(process)); handlers.add(new JavaBreakpointHandler.JavaFieldBreakpointHandler(process)); @@ -102,43 +104,40 @@ protected JavaDebugProcess(@Nonnull final XDebugSession session, final DebuggerS myBreakpointHandlers = handlers.toArray(new XBreakpointHandler[handlers.size()]); - myJavaSession.getContextManager().addListener(new DebuggerContextListener() { - @Override - public void changeEvent(@Nonnull final DebuggerContextImpl newContext, DebuggerSession.Event event) { - if (event == DebuggerSession.Event.PAUSE || event == DebuggerSession.Event.CONTEXT || event == DebuggerSession.Event.REFRESH && myJavaSession - .isPaused()) { - final SuspendContextImpl newSuspendContext = newContext.getSuspendContext(); - if (newSuspendContext != null && shouldApplyContext(newContext)) { - process.getManagerThread().schedule(new SuspendContextCommandImpl(newSuspendContext) { - @Override - public void contextAction() throws Exception { - newSuspendContext.initExecutionStacks(newContext.getThreadProxy()); - - List> descriptors = DebuggerUtilsEx.getEventDescriptors(newSuspendContext); - if (!descriptors.isEmpty()) { - Breakpoint breakpoint = descriptors.get(0).getFirst(); - XBreakpoint xBreakpoint = breakpoint.getXBreakpoint(); - if (xBreakpoint != null) { - getSession().breakpointReachedNoProcessing(xBreakpoint, newSuspendContext); - unsetPausedIfNeeded(newContext); - return; - } + myJavaSession.getContextManager().addListener((newContext, event) -> { + if (event == DebuggerSession.Event.PAUSE || event == DebuggerSession.Event.CONTEXT + || event == DebuggerSession.Event.REFRESH && myJavaSession.isPaused()) { + SuspendContextImpl newSuspendContext = newContext.getSuspendContext(); + if (newSuspendContext != null && shouldApplyContext(newContext)) { + process.getManagerThread().schedule(new SuspendContextCommandImpl(newSuspendContext) { + @Override + public void contextAction() throws Exception { + newSuspendContext.initExecutionStacks(newContext.getThreadProxy()); + + List> descriptors = DebuggerUtilsEx.getEventDescriptors(newSuspendContext); + if (!descriptors.isEmpty()) { + Breakpoint breakpoint = descriptors.get(0).getFirst(); + XBreakpoint xBreakpoint = breakpoint.getXBreakpoint(); + if (xBreakpoint != null) { + getSession().breakpointReachedNoProcessing(xBreakpoint, newSuspendContext); + unsetPausedIfNeeded(newContext); + return; } - getSession().positionReached(newSuspendContext); - unsetPausedIfNeeded(newContext); } - }); - } - } - else if (event == DebuggerSession.Event.ATTACHED) { - getSession().rebuildViews(); // to refresh variables views message + getSession().positionReached(newSuspendContext); + unsetPausedIfNeeded(newContext); + } + }); } } + else if (event == DebuggerSession.Event.ATTACHED) { + getSession().rebuildViews(); // to refresh variables views message + } }); myNodeManager = new NodeManagerImpl(session.getProject(), null) { @Override - public DebuggerTreeNodeImpl createNode(final NodeDescriptor descriptor, EvaluationContext evaluationContext) { + public DebuggerTreeNodeImpl createNode(NodeDescriptor descriptor, EvaluationContext evaluationContext) { return new DebuggerTreeNodeImpl(null, descriptor); } @@ -162,9 +161,9 @@ public void sessionPaused() { @Override public void stackFrameChanged() { XStackFrame frame = session.getCurrentStackFrame(); - if (frame instanceof JavaStackFrame) { + if (frame instanceof JavaStackFrame javaStackFrame) { showAlternativeNotification(frame); - StackFrameProxyImpl frameProxy = ((JavaStackFrame) frame).getStackFrameProxy(); + StackFrameProxyImpl frameProxy = javaStackFrame.getStackFrameProxy(); DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), frameProxy); saveNodeHistory(frameProxy); } @@ -196,7 +195,7 @@ private void unsetPausedIfNeeded(DebuggerContextImpl context) { private boolean shouldApplyContext(DebuggerContextImpl context) { SuspendContextImpl suspendContext = context.getSuspendContext(); - SuspendContextImpl currentContext = (SuspendContextImpl) getSession().getSuspendContext(); + SuspendContextImpl currentContext = (SuspendContextImpl)getSession().getSuspendContext(); if (suspendContext != null && !suspendContext.equals(currentContext)) { return true; } @@ -208,7 +207,7 @@ public void saveNodeHistory() { saveNodeHistory(getDebuggerStateManager().getContext().getFrameProxy()); } - private void saveNodeHistory(final StackFrameProxyImpl frameProxy) { + private void saveNodeHistory(StackFrameProxyImpl frameProxy) { myJavaSession.getProcess().getManagerThread().invoke(new DebuggerCommandImpl() { @Override protected void action() throws Exception { @@ -237,21 +236,25 @@ public XDebuggerEditorsProvider getEditorsProvider() { } @Override + @RequiredUIAccess public void startStepOver() { myJavaSession.stepOver(false); } @Override + @RequiredUIAccess public void startStepInto() { myJavaSession.stepInto(false, null); } @Override + @RequiredUIAccess public void startForceStepInto() { myJavaSession.stepInto(true, null); } @Override + @RequiredUIAccess public void startStepOut() { myJavaSession.stepOut(); } @@ -268,11 +271,13 @@ public void startPausing() { } @Override + @RequiredUIAccess public void resume() { myJavaSession.resume(); } @Override + @RequiredUIAccess public void runToPosition(@Nonnull XSourcePosition position) { myJavaSession.runToCursor(position, false); } @@ -318,8 +323,8 @@ public void registerAdditionalContent(@Nonnull RunnerLayoutUi ui) { @Override public Content registerConsoleContent(@Nonnull RunnerLayoutUi ui, @Nonnull ExecutionConsole console) { Content content = null; - if (console instanceof ExecutionConsoleEx) { - ((ExecutionConsoleEx) console).buildUi(ui); + if (console instanceof ExecutionConsoleEx consoleEx) { + consoleEx.buildUi(ui); content = ui.findContent(DebuggerContentInfo.CONSOLE_CONTENT); } if (content == null) { @@ -329,12 +334,14 @@ public Content registerConsoleContent(@Nonnull RunnerLayoutUi ui, @Nonnull Execu } private void registerThreadsPanel(@Nonnull RunnerLayoutUi ui) { - final ThreadsPanel panel = new ThreadsPanel(myJavaSession.getProject(), getDebuggerStateManager()); - final Content threadsContent = ui.createContent(DebuggerContentInfo.THREADS_CONTENT, + ThreadsPanel panel = new ThreadsPanel(myJavaSession.getProject(), getDebuggerStateManager()); + Content threadsContent = ui.createContent( + DebuggerContentInfo.THREADS_CONTENT, panel, - XDebuggerBundle.message("debugger.session.tab.threads.title"), + XDebuggerLocalize.debuggerSessionTabThreadsTitle().get(), ExecutionDebugIconGroup.threadThreads(), - null); + null + ); threadsContent.setCloseable(false); ui.addContent(threadsContent, 0, PlaceInGrid.left, true); ui.addListener(new ContentManagerAdapter() { @@ -356,13 +363,13 @@ public void selectionChanged(ContentManagerEvent event) { } // private void registerMemoryViewPanel(@Nonnull RunnerLayoutUi ui) { -// final XDebugSession session = getSession(); -// final DebugProcessImpl process = myJavaSession.getProcess(); -// final InstancesTracker tracker = InstancesTracker.getInstance(myJavaSession.getProject()); +// XDebugSession session = getSession(); +// DebugProcessImpl process = myJavaSession.getProcess(); +// InstancesTracker tracker = InstancesTracker.getInstance(myJavaSession.getProject()); // -// final ClassesFilteredView classesFilteredView = new ClassesFilteredView(session, process, tracker); +// ClassesFilteredView classesFilteredView = new ClassesFilteredView(session, process, tracker); // -// final Content memoryViewContent = ui.createContent(MemoryViewManager.MEMORY_VIEW_CONTENT, +// Content memoryViewContent = ui.createContent(MemoryViewManager.MEMORY_VIEW_CONTENT, // classesFilteredView, // "Memory View", // ExecutionDebugIconGroup.nodeMemory(), @@ -371,7 +378,7 @@ public void selectionChanged(ContentManagerEvent event) { // memoryViewContent.setCloseable(false); // memoryViewContent.setShouldDisposeContent(true); // -// final MemoryViewDebugProcessData data = new MemoryViewDebugProcessData(); +// MemoryViewDebugProcessData data = new MemoryViewDebugProcessData(); // process.putUserData(MemoryViewDebugProcessData.KEY, data); // session.addSessionListener(new XDebugSessionListener() { // @Override @@ -382,23 +389,28 @@ public void selectionChanged(ContentManagerEvent event) { // }); // // ui.addContent(memoryViewContent, 0, PlaceInGrid.right, true); -// final DebuggerManagerThreadImpl managerThread = process.getManagerThread(); -// ui.addListener(new ContentManagerAdapter() { -// @Override -// public void selectionChanged(ContentManagerEvent event) { -// if (event != null && event.getContent() == memoryViewContent) { -// classesFilteredView.setActive(memoryViewContent.isSelected(), managerThread); +// DebuggerManagerThreadImpl managerThread = process.getManagerThread(); +// ui.addListener( +// new ContentManagerAdapter() { +// @Override +// public void selectionChanged(ContentManagerEvent event) { +// if (event != null && event.getContent() == memoryViewContent) { +// classesFilteredView.setActive(memoryViewContent.isSelected(), managerThread); +// } // } -// } -// }, memoryViewContent); +// }, +// memoryViewContent +// ); // } }; } @Override - public void registerAdditionalActions(@Nonnull DefaultActionGroup leftToolbar, - @Nonnull DefaultActionGroup topToolbar, - @Nonnull DefaultActionGroup settings) { + public void registerAdditionalActions( + @Nonnull DefaultActionGroup leftToolbar, + @Nonnull DefaultActionGroup topToolbar, + @Nonnull DefaultActionGroup settings + ) { Constraints beforeRunner = new Constraints(Anchor.BEFORE, "Runner.Layout"); leftToolbar.add(AnSeparator.getInstance(), beforeRunner); leftToolbar.add(ActionManager.getInstance().getAction(DebuggerActions.DUMP_THREADS), beforeRunner); @@ -413,12 +425,15 @@ private static class AutoVarsSwitchAction extends ToggleAction { private volatile boolean myAutoModeEnabled; public AutoVarsSwitchAction() { - super(DebuggerBundle.message("action.auto.variables.mode"), DebuggerBundle.message("action.auto.variables.mode.description"), null); + super( + JavaDebuggerLocalize.actionAutoVariablesMode(), + JavaDebuggerLocalize.actionAutoVariablesModeDescription() + ); myAutoModeEnabled = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE; } @Override - public boolean isSelected(AnActionEvent e) { + public boolean isSelected(@Nonnull AnActionEvent e) { return myAutoModeEnabled; } @@ -432,34 +447,36 @@ public void setSelected(AnActionEvent e, boolean enabled) { private static class WatchLastMethodReturnValueAction extends ToggleAction { private volatile boolean myWatchesReturnValues; - private final String myText; - private final String myTextUnavailable; + @Nonnull + private final LocalizeValue myText; + @Nonnull + private final LocalizeValue myTextUnavailable; public WatchLastMethodReturnValueAction() { - super("", DebuggerBundle.message("action.watch.method.return.value.description"), null); + super(LocalizeValue.empty(), JavaDebuggerLocalize.actionWatchMethodReturnValueDescription()); myWatchesReturnValues = DebuggerSettings.getInstance().WATCH_RETURN_VALUES; - myText = DebuggerBundle.message("action.watches.method.return.value.enable"); - myTextUnavailable = DebuggerBundle.message("action.watches.method.return.value.unavailable.reason"); + myText = JavaDebuggerLocalize.actionWatchesMethodReturnValueEnable(); + myTextUnavailable = JavaDebuggerLocalize.actionWatchesMethodReturnValueUnavailableReason(); } @RequiredUIAccess @Override - public void update(@Nonnull final AnActionEvent e) { + public void update(@Nonnull AnActionEvent e) { super.update(e); - final Presentation presentation = e.getPresentation(); + Presentation presentation = e.getPresentation(); DebugProcessImpl process = getCurrentDebugProcess(e.getData(Project.KEY)); if (process == null || process.canGetMethodReturnValue()) { presentation.setEnabled(true); - presentation.setText(myText); + presentation.setTextValue(myText); } else { presentation.setEnabled(false); - presentation.setText(myTextUnavailable); + presentation.setTextValue(myTextUnavailable); } } @Override - public boolean isSelected(AnActionEvent e) { + public boolean isSelected(@Nonnull AnActionEvent e) { return myWatchesReturnValues; } @@ -478,11 +495,8 @@ public void setSelected(AnActionEvent e, boolean watch) { private static DebugProcessImpl getCurrentDebugProcess(@Nullable Project project) { if (project != null) { XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); - if (session != null) { - XDebugProcess process = session.getDebugProcess(); - if (process instanceof JavaDebugProcess) { - return ((JavaDebugProcess) process).getDebuggerSession().getProcess(); - } + if (session != null && session.getDebugProcess() instanceof JavaDebugProcess debugProcess) { + return debugProcess.getDebuggerSession().getProcess(); } } return null; diff --git a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/ui/impl/ThreadsDebuggerTree.java b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/ui/impl/ThreadsDebuggerTree.java index 8d0783a095..06d416f549 100644 --- a/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/ui/impl/ThreadsDebuggerTree.java +++ b/java-debugger-impl/src/main/java/com/intellij/java/debugger/impl/ui/impl/ThreadsDebuggerTree.java @@ -15,293 +15,239 @@ */ package com.intellij.java.debugger.impl.ui.impl; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; - -import javax.swing.SwingUtilities; -import javax.swing.event.TreeModelEvent; -import javax.swing.tree.TreePath; - -import com.intellij.java.debugger.DebuggerBundle; +import com.intellij.java.debugger.impl.DebuggerContextImpl; import com.intellij.java.debugger.impl.DebuggerInvocationUtil; +import com.intellij.java.debugger.impl.DebuggerSession; import com.intellij.java.debugger.impl.engine.DebugProcessImpl; import com.intellij.java.debugger.impl.engine.SuspendContextImpl; import com.intellij.java.debugger.impl.engine.evaluation.EvaluationContextImpl; import com.intellij.java.debugger.impl.engine.events.DebuggerCommandImpl; -import com.intellij.java.debugger.impl.DebuggerContextImpl; -import com.intellij.java.debugger.impl.DebuggerSession; import com.intellij.java.debugger.impl.jdi.StackFrameProxyImpl; import com.intellij.java.debugger.impl.jdi.ThreadGroupReferenceProxyImpl; import com.intellij.java.debugger.impl.jdi.ThreadReferenceProxyImpl; import com.intellij.java.debugger.impl.jdi.VirtualMachineProxyImpl; import com.intellij.java.debugger.impl.settings.ThreadsViewSettings; -import com.intellij.java.debugger.impl.ui.impl.watch.DebuggerTree; -import com.intellij.java.debugger.impl.ui.impl.watch.DebuggerTreeNodeImpl; -import com.intellij.java.debugger.impl.ui.impl.watch.MessageDescriptor; -import com.intellij.java.debugger.impl.ui.impl.watch.NodeDescriptorImpl; -import com.intellij.java.debugger.impl.ui.impl.watch.NodeManagerImpl; -import com.intellij.java.debugger.impl.ui.impl.watch.StackFrameDescriptorImpl; -import com.intellij.java.debugger.impl.ui.impl.watch.ThreadDescriptorImpl; -import com.intellij.java.debugger.impl.ui.impl.watch.ThreadGroupDescriptorImpl; -import consulo.application.ApplicationManager; -import consulo.execution.debug.XDebuggerBundle; +import com.intellij.java.debugger.impl.ui.impl.watch.*; +import com.intellij.java.debugger.localize.JavaDebuggerLocalize; +import consulo.application.Application; +import consulo.execution.debug.localize.XDebuggerLocalize; +import consulo.logging.Logger; import consulo.project.Project; import consulo.ui.ex.awt.tree.TreeModelAdapter; -import consulo.logging.Logger; + +import javax.swing.*; +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; /** - * User: lex - * Date: Sep 26, 2003 - * Time: 5:57:58 PM + * @author lex + * @since 2003-09-26 */ -public class ThreadsDebuggerTree extends DebuggerTree -{ - private static final Logger LOG = Logger.getInstance(ThreadsDebuggerTree.class); - - public ThreadsDebuggerTree(Project project) - { - super(project); - getEmptyText().setText(XDebuggerBundle.message("debugger.threads.not.available")); - } - - @Override - protected NodeManagerImpl createNodeManager(Project project) - { - return new NodeManagerImpl(project, this) - { - @Override - public String getContextKey(StackFrameProxyImpl frame) - { - return "ThreadsView"; - } - }; - } - - @Override - protected boolean isExpandable(DebuggerTreeNodeImpl node) - { - NodeDescriptorImpl descriptor = node.getDescriptor(); - if(descriptor instanceof StackFrameDescriptorImpl) - { - return false; - } - return descriptor.isExpandable(); - } - - @Override - protected void build(DebuggerContextImpl context) - { - DebuggerSession session = context.getDebuggerSession(); - final RefreshThreadsTreeCommand command = new RefreshThreadsTreeCommand(session); - - final DebuggerSession.State state = session != null ? session.getState() : DebuggerSession.State.DISPOSED; - if(ApplicationManager.getApplication().isUnitTestMode() || state == DebuggerSession.State.PAUSED || state == DebuggerSession.State.RUNNING) - { - showMessage(MessageDescriptor.EVALUATING); - context.getDebugProcess().getManagerThread().schedule(command); - } - else - { - showMessage(session != null ? session.getStateDescription() : DebuggerBundle.message("status.debug.stopped")); - } - } - - private class RefreshThreadsTreeCommand extends DebuggerCommandImpl - { - private final DebuggerSession mySession; - - public RefreshThreadsTreeCommand(DebuggerSession session) - { - mySession = session; - } - - @Override - protected void action() throws Exception - { - final DebuggerTreeNodeImpl root = getNodeFactory().getDefaultNode(); - - final DebugProcessImpl debugProcess = mySession.getProcess(); - if(!debugProcess.isAttached()) - { - return; - } - final DebuggerContextImpl context = mySession.getContextManager().getContext(); - final SuspendContextImpl suspendContext = context.getSuspendContext(); - final ThreadReferenceProxyImpl suspendContextThread = suspendContext != null ? suspendContext.getThread() : null; - - final boolean showGroups = ThreadsViewSettings.getInstance().SHOW_THREAD_GROUPS; - try - { - final ThreadReferenceProxyImpl currentThread = ThreadsViewSettings.getInstance().SHOW_CURRENT_THREAD ? suspendContextThread : null; - final VirtualMachineProxyImpl vm = debugProcess.getVirtualMachineProxy(); - - final EvaluationContextImpl evaluationContext = suspendContext != null ? getDebuggerContext().createEvaluationContext() : null; - final NodeManagerImpl nodeManager = getNodeFactory(); - - if(showGroups) - { - ThreadGroupReferenceProxyImpl topCurrentGroup = null; - - if(currentThread != null) - { - topCurrentGroup = currentThread.threadGroupProxy(); - if(topCurrentGroup != null) - { - for(ThreadGroupReferenceProxyImpl parentGroup = topCurrentGroup.parent(); parentGroup != null; parentGroup = parentGroup.parent()) - { - topCurrentGroup = parentGroup; - } - } - - if(topCurrentGroup != null) - { - root.add(nodeManager.createNode(nodeManager.getThreadGroupDescriptor(null, topCurrentGroup), evaluationContext)); - } - else - { - root.add(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext)); - } - } - - for(ThreadGroupReferenceProxyImpl group : vm.topLevelThreadGroups()) - { - if(group != topCurrentGroup) - { - DebuggerTreeNodeImpl threadGroup = nodeManager.createNode(nodeManager.getThreadGroupDescriptor(null, group), evaluationContext); - root.add(threadGroup); - } - } - } - else - { - // do not show thread groups - if(currentThread != null) - { - root.insert(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext), 0); - } - List allThreads = new ArrayList(vm.allThreads()); - Collections.sort(allThreads, ThreadReferenceProxyImpl.ourComparator); - - for(ThreadReferenceProxyImpl threadProxy : allThreads) - { - if(threadProxy.equals(currentThread)) - { - continue; - } - root.add(nodeManager.createNode(nodeManager.getThreadDescriptor(null, threadProxy), evaluationContext)); - } - } - } - catch(Exception ex) - { - root.add(MessageDescriptor.DEBUG_INFO_UNAVAILABLE); - if(LOG.isDebugEnabled()) - { - LOG.debug(ex); - } - } - - final boolean hasThreadToSelect = suspendContextThread != null; // thread can be null if pause was pressed - final List groups; - if(hasThreadToSelect && showGroups) - { - groups = new ArrayList(); - for(ThreadGroupReferenceProxyImpl group = suspendContextThread.threadGroupProxy(); group != null; group = group.parent()) - { - groups.add(group); - } - Collections.reverse(groups); - } - else - { - groups = Collections.emptyList(); - } - - DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() - { - @Override - public void run() - { - getMutableModel().setRoot(root); - treeChanged(); - if(hasThreadToSelect) - { - selectThread(groups, suspendContextThread, true); - } - } - }); - } - - private void selectThread(final List pathToThread, final ThreadReferenceProxyImpl thread, final boolean expand) - { - LOG.assertTrue(SwingUtilities.isEventDispatchThread()); - class MyTreeModelAdapter extends TreeModelAdapter - { - private void structureChanged(DebuggerTreeNodeImpl node) - { - for(Enumeration enumeration = node.children(); enumeration.hasMoreElements(); ) - { - DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl) enumeration.nextElement(); - nodeChanged(child); - } - } - - private void nodeChanged(DebuggerTreeNodeImpl debuggerTreeNode) - { - if(pathToThread.size() == 0) - { - if(debuggerTreeNode.getDescriptor() instanceof ThreadDescriptorImpl && ((ThreadDescriptorImpl) debuggerTreeNode.getDescriptor()).getThreadReference() == thread) - { - removeListener(); - final TreePath treePath = new TreePath(debuggerTreeNode.getPath()); - setSelectionPath(treePath); - if(expand && !isExpanded(treePath)) - { - expandPath(treePath); - } - } - } - else - { - if(debuggerTreeNode.getDescriptor() instanceof ThreadGroupDescriptorImpl && ((ThreadGroupDescriptorImpl) debuggerTreeNode.getDescriptor()).getThreadGroupReference() == - pathToThread.get(0)) - { - pathToThread.remove(0); - expandPath(new TreePath(debuggerTreeNode.getPath())); - } - } - } - - private void removeListener() - { - final TreeModelAdapter listener = this; - SwingUtilities.invokeLater(new Runnable() - { - @Override - public void run() - { - getModel().removeTreeModelListener(listener); - } - }); - } - - @Override - public void treeStructureChanged(TreeModelEvent event) - { - if(event.getPath().length <= 1) - { - removeListener(); - return; - } - structureChanged((DebuggerTreeNodeImpl) event.getTreePath().getLastPathComponent()); - } - } - - MyTreeModelAdapter listener = new MyTreeModelAdapter(); - listener.structureChanged((DebuggerTreeNodeImpl) getModel().getRoot()); - getModel().addTreeModelListener(listener); - } - } +public class ThreadsDebuggerTree extends DebuggerTree { + private static final Logger LOG = Logger.getInstance(ThreadsDebuggerTree.class); + + public ThreadsDebuggerTree(Project project) { + super(project); + getEmptyText().setText(XDebuggerLocalize.debuggerThreadsNotAvailable().get()); + } + + @Override + protected NodeManagerImpl createNodeManager(Project project) { + return new NodeManagerImpl(project, this) { + @Override + public String getContextKey(StackFrameProxyImpl frame) { + return "ThreadsView"; + } + }; + } + + @Override + protected boolean isExpandable(DebuggerTreeNodeImpl node) { + NodeDescriptorImpl descriptor = node.getDescriptor(); + return !(descriptor instanceof StackFrameDescriptorImpl) && descriptor.isExpandable(); + } + + @Override + protected void build(DebuggerContextImpl context) { + DebuggerSession session = context.getDebuggerSession(); + final RefreshThreadsTreeCommand command = new RefreshThreadsTreeCommand(session); + + final DebuggerSession.State state = session != null ? session.getState() : DebuggerSession.State.DISPOSED; + if (Application.get().isUnitTestMode() + || state == DebuggerSession.State.PAUSED + || state == DebuggerSession.State.RUNNING) { + showMessage(MessageDescriptor.EVALUATING); + context.getDebugProcess().getManagerThread().schedule(command); + } + else { + showMessage(session != null ? session.getStateDescription() : JavaDebuggerLocalize.statusDebugStopped().get()); + } + } + + private class RefreshThreadsTreeCommand extends DebuggerCommandImpl { + private final DebuggerSession mySession; + + public RefreshThreadsTreeCommand(DebuggerSession session) { + mySession = session; + } + + @Override + protected void action() throws Exception { + final DebuggerTreeNodeImpl root = getNodeFactory().getDefaultNode(); + + final DebugProcessImpl debugProcess = mySession.getProcess(); + if (!debugProcess.isAttached()) { + return; + } + final DebuggerContextImpl context = mySession.getContextManager().getContext(); + final SuspendContextImpl suspendContext = context.getSuspendContext(); + final ThreadReferenceProxyImpl suspendContextThread = suspendContext != null ? suspendContext.getThread() : null; + + final boolean showGroups = ThreadsViewSettings.getInstance().SHOW_THREAD_GROUPS; + try { + final ThreadReferenceProxyImpl currentThread = + ThreadsViewSettings.getInstance().SHOW_CURRENT_THREAD ? suspendContextThread : null; + final VirtualMachineProxyImpl vm = debugProcess.getVirtualMachineProxy(); + + final EvaluationContextImpl evaluationContext = + suspendContext != null ? getDebuggerContext().createEvaluationContext() : null; + final NodeManagerImpl nodeManager = getNodeFactory(); + + if (showGroups) { + ThreadGroupReferenceProxyImpl topCurrentGroup = null; + + if (currentThread != null) { + topCurrentGroup = currentThread.threadGroupProxy(); + if (topCurrentGroup != null) { + for (ThreadGroupReferenceProxyImpl parentGroup = topCurrentGroup.parent(); parentGroup != null; + parentGroup = parentGroup.parent()) { + topCurrentGroup = parentGroup; + } + } + + if (topCurrentGroup != null) { + root.add(nodeManager.createNode( + nodeManager.getThreadGroupDescriptor(null, topCurrentGroup), + evaluationContext + )); + } + else { + root.add(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext)); + } + } + + for (ThreadGroupReferenceProxyImpl group : vm.topLevelThreadGroups()) { + if (group != topCurrentGroup) { + DebuggerTreeNodeImpl threadGroup = + nodeManager.createNode(nodeManager.getThreadGroupDescriptor(null, group), evaluationContext); + root.add(threadGroup); + } + } + } + else { + // do not show thread groups + if (currentThread != null) { + root.insert(nodeManager.createNode(nodeManager.getThreadDescriptor(null, currentThread), evaluationContext), 0); + } + List allThreads = new ArrayList<>(vm.allThreads()); + Collections.sort(allThreads, ThreadReferenceProxyImpl.ourComparator); + + for (ThreadReferenceProxyImpl threadProxy : allThreads) { + if (threadProxy.equals(currentThread)) { + continue; + } + root.add(nodeManager.createNode(nodeManager.getThreadDescriptor(null, threadProxy), evaluationContext)); + } + } + } + catch (Exception ex) { + root.add(MessageDescriptor.DEBUG_INFO_UNAVAILABLE); + if (LOG.isDebugEnabled()) { + LOG.debug(ex); + } + } + + final boolean hasThreadToSelect = suspendContextThread != null; // thread can be null if pause was pressed + final List groups; + if (hasThreadToSelect && showGroups) { + groups = new ArrayList<>(); + for (ThreadGroupReferenceProxyImpl group = suspendContextThread.threadGroupProxy(); group != null; group = group.parent()) { + groups.add(group); + } + Collections.reverse(groups); + } + else { + groups = Collections.emptyList(); + } + + DebuggerInvocationUtil.swingInvokeLater( + getProject(), + () -> { + getMutableModel().setRoot(root); + treeChanged(); + if (hasThreadToSelect) { + selectThread(groups, suspendContextThread, true); + } + } + ); + } + + private void selectThread( + final List pathToThread, + final ThreadReferenceProxyImpl thread, + final boolean expand + ) { + LOG.assertTrue(SwingUtilities.isEventDispatchThread()); + class MyTreeModelAdapter extends TreeModelAdapter { + private void structureChanged(DebuggerTreeNodeImpl node) { + for (Enumeration enumeration = node.children(); enumeration.hasMoreElements(); ) { + DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)enumeration.nextElement(); + nodeChanged(child); + } + } + + private void nodeChanged(DebuggerTreeNodeImpl debuggerTreeNode) { + if (pathToThread.size() == 0) { + if (debuggerTreeNode.getDescriptor() instanceof ThreadDescriptorImpl && ((ThreadDescriptorImpl)debuggerTreeNode.getDescriptor()).getThreadReference() == thread) { + removeListener(); + final TreePath treePath = new TreePath(debuggerTreeNode.getPath()); + setSelectionPath(treePath); + if (expand && !isExpanded(treePath)) { + expandPath(treePath); + } + } + } + else { + if (debuggerTreeNode.getDescriptor() instanceof ThreadGroupDescriptorImpl && ((ThreadGroupDescriptorImpl)debuggerTreeNode.getDescriptor()).getThreadGroupReference() == + pathToThread.get(0)) { + pathToThread.remove(0); + expandPath(new TreePath(debuggerTreeNode.getPath())); + } + } + } + + private void removeListener() { + final TreeModelAdapter listener = this; + SwingUtilities.invokeLater(() -> getModel().removeTreeModelListener(listener)); + } + + @Override + public void treeStructureChanged(TreeModelEvent event) { + if (event.getPath().length <= 1) { + removeListener(); + return; + } + structureChanged((DebuggerTreeNodeImpl)event.getTreePath().getLastPathComponent()); + } + } + + MyTreeModelAdapter listener = new MyTreeModelAdapter(); + listener.structureChanged((DebuggerTreeNodeImpl)getModel().getRoot()); + getModel().addTreeModelListener(listener); + } + } }