1. added "copy to clipboard" action to thread dump console
[fedora-idea.git] / java / java-impl / src / com / intellij / unscramble / ThreadDumpPanel.java
blob619489f944778b95b81c1cd1a52e5f1274e342b3
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;
18 import javax.swing.*;
19 import javax.swing.event.ListSelectionEvent;
20 import javax.swing.event.ListSelectionListener;
21 import java.awt.*;
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();
44 if (index >= 0) {
45 ThreadState selection = threadDump.get(index);
46 AnalyzeStacktraceUtil.printStacktrace(consoleView, selection.getStackTrace());
48 else {
49 AnalyzeStacktraceUtil.printStacktrace(consoleView, "");
51 myThreadList.repaint();
53 });
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()) {
67 return PAUSE_ICON;
69 if (threadState.isWaiting()) {
70 return LOCKED_ICON;
72 if (threadState.getOperation() == ThreadOperation.Socket) {
73 return SOCKET_ICON;
75 if (threadState.getOperation() == ThreadOperation.IO) {
76 return IO_ICON;
78 if (threadState.isEDT()) {
79 if ("idle".equals(threadState.getThreadStateDetail())) {
80 return IDLE_ICON;
82 return EDT_BUSY_ICON;
84 return RUNNING_ICON;
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));
105 if (!selected) {
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);
113 else {
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);
127 append(")", 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;
146 myProject = project;
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() {
156 public void run() {
157 if (!myProject.isDisposed()) {
158 ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.RUN, MessageType.INFO, "Full thread dump was successfully copied to clipboard");