KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > example > debug > gui > StackTraceTool


1 /*
2  * @(#)StackTraceTool.java 1.14 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
11  * modify and redistribute this software in source and binary code form,
12  * provided that i) this copyright notice and license appear on all copies of
13  * the software; and ii) Licensee does not utilize the software in a manner
14  * which is disparaging to Sun.
15  *
16  * This software is provided "AS IS," without a warranty of any kind. ALL
17  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
18  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
20  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
21  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
22  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
23  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
24  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
25  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGES.
27  *
28  * This software is not designed or intended for use in on-line control of
29  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
30  * the design, construction, operation or maintenance of any nuclear
31  * facility. Licensee represents and warrants that it will not use or
32  * redistribute the Software for such purposes.
33  */

34
35 package com.sun.tools.example.debug.gui;
36
37 import java.io.*;
38 import java.util.*;
39 import java.util.List JavaDoc; // Must import explicitly due to conflict with javax.awt.List
40

41 import javax.swing.*;
42 import javax.swing.tree.*;
43 import javax.swing.event.*;
44 import java.awt.*;
45 import java.awt.event.*;
46
47 import com.sun.jdi.*;
48 import com.sun.tools.example.debug.bdi.*;
49
50 public class StackTraceTool extends JPanel {
51
52     private Environment env;
53
54     private ExecutionManager runtime;
55     private ContextManager context;
56
57     private ThreadInfo tinfo;
58
59     private JList list;
60     private ListModel stackModel;
61
62     public StackTraceTool(Environment env) {
63
64     super(new BorderLayout());
65
66     this.env = env;
67     this.runtime = env.getExecutionManager();
68     this.context = env.getContextManager();
69     
70     stackModel = new DefaultListModel(); // empty
71

72         list = new JList(stackModel);
73     list.setCellRenderer(new StackFrameRenderer());
74
75     JScrollPane listView = new JScrollPane(list);
76     add(listView);
77
78     // Create listener.
79
StackTraceToolListener listener = new StackTraceToolListener();
80     context.addContextListener(listener);
81         list.addListSelectionListener(listener);
82
83         //### remove listeners on exit!
84
}
85
86     private class StackTraceToolListener
87         implements ContextListener, ListSelectionListener
88     {
89
90     // ContextListener
91

92     // If the user selects a new current frame, display it in
93
// this view.
94

95     //### I suspect we handle the case badly that the VM is not interrupted.
96

97     public void currentFrameChanged(CurrentFrameChangedEvent e) {
98         // If the current frame of the thread appearing in this
99
// view is changed, move the selection to track it.
100
int frameIndex = e.getIndex();
101             ThreadInfo ti = e.getThreadInfo();
102         if (e.getInvalidate() || tinfo != ti) {
103                 tinfo = ti;
104                 showStack(ti, frameIndex);
105             } else {
106         if (frameIndex < stackModel.getSize()) {
107             list.setSelectedIndex(frameIndex);
108             list.ensureIndexIsVisible(frameIndex);
109         }
110             }
111     }
112
113         // ListSelectionListener
114

115         public void valueChanged(ListSelectionEvent e) {
116             int index = list.getSelectedIndex();
117             if (index != -1) {
118                 //### should use listener?
119
try {
120                     context.setCurrentFrameIndex(index);
121                 } catch (VMNotInterruptedException exc) {
122                 }
123             }
124         }
125     }
126
127     private class StackFrameRenderer extends DefaultListCellRenderer {
128
129     public Component getListCellRendererComponent(JList list,
130                               Object JavaDoc value,
131                               int index,
132                               boolean isSelected,
133                               boolean cellHasFocus) {
134
135         //### We should indicate the current thread independently of the
136
//### selection, e.g., with an icon, because the user may change
137
//### the selection graphically without affecting the current
138
//### thread.
139

140         super.getListCellRendererComponent(list, value, index,
141                                                isSelected, cellHasFocus);
142             if (value == null) {
143                 this.setText("<unavailable>");
144             } else {
145                 StackFrame frame = (StackFrame)value;
146                 Location loc = frame.location();
147                 Method meth = loc.method();
148                 String JavaDoc methName =
149                     meth.declaringType().name() + '.' + meth.name();
150                 String JavaDoc position = "";
151                 if (meth instanceof Method && ((Method)meth).isNative()) {
152                     position = " (native method)";
153                 } else if (loc.lineNumber() != -1) {
154                     position = ":" + loc.lineNumber();
155                 } else {
156                     long pc = loc.codeIndex();
157                     if (pc != -1) {
158                         position = ", pc = " + pc;
159                     }
160                 }
161                 // Indices are presented to the user starting from 1, not 0.
162
this.setText("[" + (index+1) +"] " + methName + position);
163             }
164         return this;
165     }
166     }
167
168     // Point this view at the given thread and frame.
169

170     private void showStack(ThreadInfo tinfo, int selectFrame) {
171     StackTraceListModel model = new StackTraceListModel(tinfo);
172     stackModel = model;
173     list.setModel(stackModel);
174     list.setSelectedIndex(selectFrame);
175     list.ensureIndexIsVisible(selectFrame);
176     }
177
178     private static class StackTraceListModel extends AbstractListModel {
179
180     private final ThreadInfo tinfo;
181     
182     public StackTraceListModel(ThreadInfo tinfo) {
183         this.tinfo = tinfo;
184     }
185     
186     public Object JavaDoc getElementAt(int index) {
187         try {
188         return tinfo == null? null : tinfo.getFrame(index);
189         } catch (VMNotInterruptedException e) {
190         //### Is this the right way to handle this?
191
//### Would happen if user scrolled stack trace
192
//### while not interrupted -- should probably
193
//### block user interaction in this case.
194
return null;
195         }
196     }
197     
198     public int getSize() {
199         try {
200         return tinfo == null? 1 : tinfo.getFrameCount();
201         } catch (VMNotInterruptedException e) {
202         //### Is this the right way to handle this?
203
return 0;
204         }
205     }
206     }
207 }
208
Popular Tags