1 package com
.intellij
.unscramble
;
3 import com
.intellij
.execution
.ui
.ConsoleView
;
4 import com
.intellij
.openapi
.actionSystem
.*;
5 import com
.intellij
.openapi
.ide
.CopyPasteManager
;
6 import com
.intellij
.openapi
.project
.Project
;
7 import com
.intellij
.openapi
.ui
.MessageType
;
8 import com
.intellij
.openapi
.ui
.Splitter
;
9 import com
.intellij
.openapi
.util
.IconLoader
;
10 import com
.intellij
.openapi
.wm
.ToolWindowId
;
11 import com
.intellij
.openapi
.wm
.ToolWindowManager
;
12 import com
.intellij
.ui
.ColoredListCellRenderer
;
13 import com
.intellij
.ui
.LightColors
;
14 import com
.intellij
.ui
.ListToolTipHandler
;
15 import com
.intellij
.ui
.SimpleTextAttributes
;
16 import com
.intellij
.util
.ui
.UIUtil
;
19 import javax
.swing
.event
.ListSelectionEvent
;
20 import javax
.swing
.event
.ListSelectionListener
;
22 import java
.awt
.datatransfer
.StringSelection
;
23 import java
.util
.List
;
25 public class ThreadDumpPanel
extends JPanel
{
26 private static final Icon PAUSE_ICON
= IconLoader
.getIcon("/debugger/threadStates/paused.png");
27 private static final Icon LOCKED_ICON
= IconLoader
.getIcon("/debugger/threadStates/locked.png");
28 private static final Icon RUNNING_ICON
= IconLoader
.getIcon("/debugger/threadStates/running.png");
29 private static final Icon SOCKET_ICON
= IconLoader
.getIcon("/debugger/threadStates/socket.png");
30 private static final Icon IDLE_ICON
= IconLoader
.getIcon("/debugger/threadStates/idle.png");
31 private static final Icon EDT_BUSY_ICON
= IconLoader
.getIcon("/debugger/threadStates/edtBusy.png");
32 private static final Icon IO_ICON
= IconLoader
.getIcon("/debugger/threadStates/io.png");
33 private JList myThreadList
;
35 public ThreadDumpPanel(Project project
, final ConsoleView consoleView
, final DefaultActionGroup toolbarActions
, final List
<ThreadState
> threadDump
) {
36 super(new BorderLayout());
38 myThreadList
= new JList(threadDump
.toArray(new ThreadState
[threadDump
.size()]));
39 myThreadList
.setCellRenderer(new ThreadListCellRenderer());
40 myThreadList
.setSelectionMode(ListSelectionModel
.SINGLE_SELECTION
);
41 myThreadList
.addListSelectionListener(new ListSelectionListener() {
42 public void valueChanged(final ListSelectionEvent e
) {
43 int index
= myThreadList
.getSelectedIndex();
45 ThreadState selection
= threadDump
.get(index
);
46 AnalyzeStacktraceUtil
.printStacktrace(consoleView
, selection
.getStackTrace());
49 AnalyzeStacktraceUtil
.printStacktrace(consoleView
, "");
51 myThreadList
.repaint();
54 ListToolTipHandler
.install(myThreadList
);
55 toolbarActions
.add(new CopyToClipboardAction(threadDump
, project
));
56 add(ActionManager
.getInstance().createActionToolbar(ActionPlaces
.UNKNOWN
, toolbarActions
,false).getComponent(), BorderLayout
.WEST
);
58 final Splitter splitter
= new Splitter(false, 0.3f
);
59 splitter
.setFirstComponent(new JScrollPane(myThreadList
));
60 splitter
.setSecondComponent(consoleView
.getComponent());
62 add(splitter
, BorderLayout
.CENTER
);
65 private static Icon
getThreadStateIcon(final ThreadState threadState
) {
66 if (threadState
.isSleeping()) {
69 if (threadState
.isWaiting()) {
72 if (threadState
.getOperation() == ThreadOperation
.Socket
) {
75 if (threadState
.getOperation() == ThreadOperation
.IO
) {
78 if (threadState
.isEDT()) {
79 if ("idle".equals(threadState
.getThreadStateDetail())) {
87 private static SimpleTextAttributes
getAttributes(final ThreadState threadState
) {
88 if (threadState
.isSleeping()) {
89 return SimpleTextAttributes
.GRAY_ATTRIBUTES
;
91 if (threadState
.isEmptyStackTrace() || ThreadDumpParser
.isKnownJdkThread(threadState
)) {
92 return new SimpleTextAttributes(SimpleTextAttributes
.STYLE_PLAIN
, Color
.GRAY
.brighter());
94 if (threadState
.isEDT()) {
95 return SimpleTextAttributes
.REGULAR_BOLD_ATTRIBUTES
;
97 return SimpleTextAttributes
.REGULAR_ATTRIBUTES
;
100 private static class ThreadListCellRenderer
extends ColoredListCellRenderer
{
102 protected void customizeCellRenderer(final JList list
, final Object value
, final int index
, final boolean selected
, final boolean hasFocus
) {
103 ThreadState threadState
= (ThreadState
) value
;
104 setIcon(getThreadStateIcon(threadState
));
106 ThreadState selectedThread
= (ThreadState
)list
.getSelectedValue();
107 if (threadState
.isDeadlocked()) {
108 setBackground(LightColors
.RED
);
110 else if (selectedThread
!= null && threadState
.isAwaitedBy(selectedThread
)) {
111 setBackground(Color
.YELLOW
);
114 setBackground(UIUtil
.getListBackground());
117 SimpleTextAttributes attrs
= getAttributes(threadState
);
118 append(threadState
.getName() + " (", attrs
);
119 String detail
= threadState
.getThreadStateDetail();
120 if (detail
== null) {
121 detail
= threadState
.getState();
123 if (detail
.length() > 30) {
124 detail
= detail
.substring(0, 30) + "...";
126 append(detail
, attrs
);
128 if (threadState
.getExtraState() != null) {
129 append(" [" + threadState
.getExtraState() + "]", attrs
);
134 public void selectStackFrame(int index
) {
135 myThreadList
.setSelectedIndex(index
);
139 private static class CopyToClipboardAction
extends AnAction
{
140 private final List
<ThreadState
> myThreadDump
;
141 private final Project myProject
;
143 public CopyToClipboardAction(List
<ThreadState
> threadDump
, Project project
) {
144 super("Copy to Clipboard", "Copy whole thread dump to clipboard", IconLoader
.getIcon("/general/copy.png"));
145 myThreadDump
= threadDump
;
149 public void actionPerformed(AnActionEvent e
) {
150 final StringBuilder buf
= new StringBuilder();
151 for (ThreadState state
: myThreadDump
) {
152 buf
.append(state
.getStackTrace()).append("\n\n");
154 CopyPasteManager
.getInstance().setContents(new StringSelection(buf
.toString()));
155 SwingUtilities
.invokeLater(new Runnable() {
157 if (!myProject
.isDisposed()) {
158 ToolWindowManager
.getInstance(myProject
).notifyByBalloon(ToolWindowId
.RUN
, MessageType
.INFO
, "Full thread dump was successfully copied to clipboard");