2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.unscramble
;
18 import com
.intellij
.execution
.ui
.ConsoleView
;
19 import com
.intellij
.openapi
.actionSystem
.*;
20 import com
.intellij
.openapi
.ide
.CopyPasteManager
;
21 import com
.intellij
.openapi
.project
.Project
;
22 import com
.intellij
.openapi
.ui
.MessageType
;
23 import com
.intellij
.openapi
.ui
.Splitter
;
24 import com
.intellij
.openapi
.util
.IconLoader
;
25 import com
.intellij
.openapi
.wm
.ToolWindowId
;
26 import com
.intellij
.openapi
.wm
.ToolWindowManager
;
27 import com
.intellij
.ui
.ColoredListCellRenderer
;
28 import com
.intellij
.ui
.LightColors
;
29 import com
.intellij
.ui
.ListToolTipHandler
;
30 import com
.intellij
.ui
.SimpleTextAttributes
;
31 import com
.intellij
.util
.ui
.UIUtil
;
34 import javax
.swing
.event
.ListSelectionEvent
;
35 import javax
.swing
.event
.ListSelectionListener
;
37 import java
.awt
.datatransfer
.StringSelection
;
38 import java
.util
.List
;
40 public class ThreadDumpPanel
extends JPanel
{
41 private static final Icon PAUSE_ICON
= IconLoader
.getIcon("/debugger/threadStates/paused.png");
42 private static final Icon LOCKED_ICON
= IconLoader
.getIcon("/debugger/threadStates/locked.png");
43 private static final Icon RUNNING_ICON
= IconLoader
.getIcon("/debugger/threadStates/running.png");
44 private static final Icon SOCKET_ICON
= IconLoader
.getIcon("/debugger/threadStates/socket.png");
45 private static final Icon IDLE_ICON
= IconLoader
.getIcon("/debugger/threadStates/idle.png");
46 private static final Icon EDT_BUSY_ICON
= IconLoader
.getIcon("/debugger/threadStates/edtBusy.png");
47 private static final Icon IO_ICON
= IconLoader
.getIcon("/debugger/threadStates/io.png");
48 private JList myThreadList
;
50 public ThreadDumpPanel(Project project
, final ConsoleView consoleView
, final DefaultActionGroup toolbarActions
, final List
<ThreadState
> threadDump
) {
51 super(new BorderLayout());
53 myThreadList
= new JList(threadDump
.toArray(new ThreadState
[threadDump
.size()]));
54 myThreadList
.setCellRenderer(new ThreadListCellRenderer());
55 myThreadList
.setSelectionMode(ListSelectionModel
.SINGLE_SELECTION
);
56 myThreadList
.addListSelectionListener(new ListSelectionListener() {
57 public void valueChanged(final ListSelectionEvent e
) {
58 int index
= myThreadList
.getSelectedIndex();
60 ThreadState selection
= threadDump
.get(index
);
61 AnalyzeStacktraceUtil
.printStacktrace(consoleView
, selection
.getStackTrace());
64 AnalyzeStacktraceUtil
.printStacktrace(consoleView
, "");
66 myThreadList
.repaint();
69 ListToolTipHandler
.install(myThreadList
);
70 toolbarActions
.add(new CopyToClipboardAction(threadDump
, project
));
71 add(ActionManager
.getInstance().createActionToolbar(ActionPlaces
.UNKNOWN
, toolbarActions
,false).getComponent(), BorderLayout
.WEST
);
73 final Splitter splitter
= new Splitter(false, 0.3f
);
74 splitter
.setFirstComponent(new JScrollPane(myThreadList
));
75 splitter
.setSecondComponent(consoleView
.getComponent());
77 add(splitter
, BorderLayout
.CENTER
);
80 private static Icon
getThreadStateIcon(final ThreadState threadState
) {
81 if (threadState
.isSleeping()) {
84 if (threadState
.isWaiting()) {
87 if (threadState
.getOperation() == ThreadOperation
.Socket
) {
90 if (threadState
.getOperation() == ThreadOperation
.IO
) {
93 if (threadState
.isEDT()) {
94 if ("idle".equals(threadState
.getThreadStateDetail())) {
102 private static SimpleTextAttributes
getAttributes(final ThreadState threadState
) {
103 if (threadState
.isSleeping()) {
104 return SimpleTextAttributes
.GRAY_ATTRIBUTES
;
106 if (threadState
.isEmptyStackTrace() || ThreadDumpParser
.isKnownJdkThread(threadState
)) {
107 return new SimpleTextAttributes(SimpleTextAttributes
.STYLE_PLAIN
, Color
.GRAY
.brighter());
109 if (threadState
.isEDT()) {
110 return SimpleTextAttributes
.REGULAR_BOLD_ATTRIBUTES
;
112 return SimpleTextAttributes
.REGULAR_ATTRIBUTES
;
115 private static class ThreadListCellRenderer
extends ColoredListCellRenderer
{
117 protected void customizeCellRenderer(final JList list
, final Object value
, final int index
, final boolean selected
, final boolean hasFocus
) {
118 ThreadState threadState
= (ThreadState
) value
;
119 setIcon(getThreadStateIcon(threadState
));
121 ThreadState selectedThread
= (ThreadState
)list
.getSelectedValue();
122 if (threadState
.isDeadlocked()) {
123 setBackground(LightColors
.RED
);
125 else if (selectedThread
!= null && threadState
.isAwaitedBy(selectedThread
)) {
126 setBackground(Color
.YELLOW
);
129 setBackground(UIUtil
.getListBackground());
132 SimpleTextAttributes attrs
= getAttributes(threadState
);
133 append(threadState
.getName() + " (", attrs
);
134 String detail
= threadState
.getThreadStateDetail();
135 if (detail
== null) {
136 detail
= threadState
.getState();
138 if (detail
.length() > 30) {
139 detail
= detail
.substring(0, 30) + "...";
141 append(detail
, attrs
);
143 if (threadState
.getExtraState() != null) {
144 append(" [" + threadState
.getExtraState() + "]", attrs
);
149 public void selectStackFrame(int index
) {
150 myThreadList
.setSelectedIndex(index
);
154 private static class CopyToClipboardAction
extends AnAction
{
155 private final List
<ThreadState
> myThreadDump
;
156 private final Project myProject
;
158 public CopyToClipboardAction(List
<ThreadState
> threadDump
, Project project
) {
159 super("Copy to Clipboard", "Copy whole thread dump to clipboard", IconLoader
.getIcon("/general/copy.png"));
160 myThreadDump
= threadDump
;
164 public void actionPerformed(AnActionEvent e
) {
165 final StringBuilder buf
= new StringBuilder();
166 for (ThreadState state
: myThreadDump
) {
167 buf
.append(state
.getStackTrace()).append("\n\n");
169 CopyPasteManager
.getInstance().setContents(new StringSelection(buf
.toString()));
170 SwingUtilities
.invokeLater(new Runnable() {
172 if (!myProject
.isDisposed()) {
173 ToolWindowManager
.getInstance(myProject
).notifyByBalloon(ToolWindowId
.RUN
, MessageType
.INFO
, "Full thread dump was successfully copied to clipboard");