001: /*
002: * ThreadPanel.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: ThreadPanel.java,v 1.5 2003/06/09 16:33:39 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j.jdb;
023:
024: import com.sun.jdi.IncompatibleThreadStateException;
025: import com.sun.jdi.Location;
026: import com.sun.jdi.Method;
027: import com.sun.jdi.StackFrame;
028: import com.sun.jdi.ThreadReference;
029: import com.sun.jdi.VirtualMachine;
030: import java.awt.Component;
031: import java.awt.event.InputEvent;
032: import java.awt.event.MouseEvent;
033: import java.awt.event.MouseListener;
034: import java.util.Iterator;
035: import java.util.List;
036: import java.util.Vector;
037: import javax.swing.JList;
038: import javax.swing.JScrollPane;
039: import javax.swing.SwingUtilities;
040: import org.armedbear.j.Buffer;
041: import org.armedbear.j.Editor;
042: import org.armedbear.j.EditorIterator;
043: import org.armedbear.j.File;
044: import org.armedbear.j.FastStringBuffer;
045: import org.armedbear.j.JavaSource;
046: import org.armedbear.j.Log;
047:
048: public final class ThreadPanel implements ContextListener,
049: MouseListener {
050: private final Jdb jdb;
051: private final JdbControlDialog dialog;
052: private final JList list;
053: private final JScrollPane scrollPane;
054:
055: private List threads;
056:
057: public ThreadPanel(Jdb jdb, JdbControlDialog dialog) {
058: this .jdb = jdb;
059: this .dialog = dialog;
060: Vector v = new Vector();
061: list = new JList(v);
062: scrollPane = new JScrollPane(list);
063: jdb.addContextListener(this );
064: list.addMouseListener(this );
065: }
066:
067: public Component getComponent() {
068: return scrollPane;
069: }
070:
071: public void contextChanged() {
072: final Vector v = new Vector();
073: int index = -1;
074: VirtualMachine vm = jdb.getVM();
075: if (vm != null) {
076: threads = vm.allThreads();
077: for (Iterator iter = threads.iterator(); iter.hasNext();) {
078: ThreadReference threadRef = (ThreadReference) iter
079: .next();
080: FastStringBuffer sb = new FastStringBuffer();
081: sb.append(threadRef.name());
082: sb.append(" (id=");
083: sb.append(threadRef.uniqueID());
084: sb.append(") ");
085: switch (threadRef.status()) {
086: case ThreadReference.THREAD_STATUS_UNKNOWN:
087: sb.append("UNKNOWN");
088: break;
089: case ThreadReference.THREAD_STATUS_ZOMBIE:
090: sb.append("ZOMBIE");
091: break;
092: case ThreadReference.THREAD_STATUS_RUNNING:
093: sb.append("RUNNING");
094: break;
095: case ThreadReference.THREAD_STATUS_SLEEPING:
096: sb.append("SLEEPING");
097: break;
098: case ThreadReference.THREAD_STATUS_MONITOR:
099: sb.append("MONITOR");
100: break;
101: case ThreadReference.THREAD_STATUS_WAIT:
102: sb.append("WAIT");
103: break;
104: case ThreadReference.THREAD_STATUS_NOT_STARTED:
105: sb.append("NOT_STARTED");
106: break;
107: }
108: if (threadRef == jdb.getCurrentThread())
109: index = v.size();
110: v.add(sb.toString());
111: }
112: }
113: // Update UI in event dispatch thread.
114: final int finalIndex = index;
115: Runnable r = new Runnable() {
116: public void run() {
117: list.setListData(v);
118: list.setSelectedIndex(finalIndex);
119: }
120: };
121: SwingUtilities.invokeLater(r);
122: }
123:
124: public void mousePressed(MouseEvent e) {
125: if (!jdb.isSuspended())
126: return;
127: // Mask off the bits we don't care about (Java 1.4).
128: int modifiers = e.getModifiers() & 0x1f;
129: if (modifiers == InputEvent.BUTTON1_MASK
130: || modifiers == InputEvent.BUTTON2_MASK) {
131: if (modifiers == InputEvent.BUTTON2_MASK)
132: list.setSelectedIndex(list
133: .locationToIndex(e.getPoint()));
134: list.paintImmediately(0, 0, list.getWidth(), list
135: .getHeight());
136: int index = list.getSelectedIndex();
137: if (threads != null && index >= 0 && index < threads.size()) {
138: ThreadReference threadRef = (ThreadReference) threads
139: .get(index);
140: jdb.setCurrentThread(threadRef);
141: try {
142: List frames = threadRef.frames();
143: if (frames.size() > 0) {
144: StackFrame stackFrame = threadRef.frame(0);
145: Location location = stackFrame.location();
146: Method method = location.method();
147: if (method != null && !method.isNative()) {
148: String className = location.declaringType()
149: .name();
150: final int lineNumber = location
151: .lineNumber();
152: Log.debug(className.concat(":").concat(
153: String.valueOf(lineNumber)));
154: File file = JavaSource.findSource(
155: className, jdb.getSourcePath());
156: if (file != null) {
157: Buffer buffer = Editor.getBuffer(file);
158: if (buffer != null) {
159: Editor editor = null;
160: for (EditorIterator it = new EditorIterator(); it
161: .hasNext();) {
162: Editor ed = it.nextEditor();
163: if (ed.getBuffer() instanceof Jdb) {
164: editor = ed;
165: break;
166: }
167: }
168: if (editor != null) {
169: editor.makeNext(buffer);
170: editor = editor
171: .activateInOtherWindow(buffer);
172: } else {
173: editor = Editor.currentEditor();
174: editor.makeNext(buffer);
175: editor.activate(buffer);
176: }
177: if (lineNumber > 0) {
178: editor
179: .jumpToLine(lineNumber - 1);
180: editor.updateDisplay();
181: }
182: }
183: }
184: }
185: }
186: // Update stack panel.
187: jdb.fireContextChanged();
188: } catch (IncompatibleThreadStateException ex) {
189: Log.error(ex);
190: }
191: }
192: }
193: dialog.requestDefaultFocus();
194: }
195:
196: public void mouseReleased(MouseEvent e) {
197: }
198:
199: public void mouseClicked(MouseEvent e) {
200: }
201:
202: public void mouseEntered(MouseEvent e) {
203: }
204:
205: public void mouseExited(MouseEvent e) {
206: }
207: }
|