KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)SourceTool.java 1.15 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
40 import java.awt.*;
41 import java.awt.event.*;
42 import javax.swing.*;
43
44 import com.sun.jdi.*;
45 import com.sun.jdi.request.*;
46
47 import com.sun.tools.example.debug.event.*;
48 import com.sun.tools.example.debug.bdi.*;
49
50 import java.util.List JavaDoc;
51
52 public class SourceTool extends JPanel {
53
54     private Environment env;
55
56     private ExecutionManager runtime;
57     private ContextManager context;
58     private SourceManager sourceManager;
59
60     private JList list;
61     private ListModel sourceModel;
62
63     // Information on source file that is on display, or failed to be
64
// displayed due to inaccessible source. Used to update display
65
// when sourcepath is changed.
66

67     private String JavaDoc sourceName; // relative path name, if showSourceFile
68
private Location sourceLocn; // location, if showSourceForLocation
69
private CommandInterpreter interpreter;
70
71     public SourceTool(Environment env) {
72
73     super(new BorderLayout());
74
75     this.env = env;
76
77     runtime = env.getExecutionManager();
78     sourceManager = env.getSourceManager();
79     this.context = env.getContextManager();
80     this.interpreter = new CommandInterpreter(env, true);
81
82     sourceModel = new DefaultListModel(); // empty
83

84     list = new JList(sourceModel);
85     list.setCellRenderer(new SourceLineRenderer());
86
87     list.setPrototypeCellValue(SourceModel.prototypeCellValue);
88
89     SourceToolListener listener = new SourceToolListener();
90     context.addContextListener(listener);
91     runtime.addSpecListener(listener);
92     sourceManager.addSourceListener(listener);
93
94         MouseListener squeek = new STMouseListener();
95         list.addMouseListener(squeek);
96
97     add(new JScrollPane(list));
98     }
99
100     public void setTextFont(Font f) {
101     list.setFont(f);
102     list.setPrototypeCellValue(SourceModel.prototypeCellValue);
103     }
104
105     private class SourceToolListener
106                implements ContextListener, SourceListener, SpecListener
107     {
108
109     // ContextListener
110

111         public void currentFrameChanged(CurrentFrameChangedEvent e) {
112             showSourceContext(e.getThread(), e.getIndex());
113         }
114
115         // Clear source view.
116
// sourceModel = new DefaultListModel(); // empty
117

118     // SourceListener
119

120     public void sourcepathChanged(SourcepathChangedEvent e) {
121         // Reload source view if its contents depend
122
// on the source path.
123
if (sourceName != null) {
124         showSourceFile(sourceName);
125         } else if (sourceLocn != null) {
126         showSourceForLocation(sourceLocn);
127         }
128     }
129
130         // SpecListener
131

132         public void breakpointSet(SpecEvent e) {
133         breakpointResolved(e);
134     }
135
136         public void breakpointDeferred(SpecEvent e) { }
137
138         public void breakpointDeleted(SpecEvent e) {
139         BreakpointRequest req = (BreakpointRequest)e.getEventRequest();
140             Location loc = req.location();
141         if (loc != null) {
142                 try {
143                     SourceModel sm = sourceManager.sourceForLocation(loc);
144                     sm.showBreakpoint(loc.lineNumber(), false);
145                     showSourceForLocation(loc);
146                 } catch (Exception JavaDoc exc) {
147                 }
148         }
149     }
150
151         public void breakpointResolved(SpecEvent e) {
152         BreakpointRequest req = (BreakpointRequest)e.getEventRequest();
153             Location loc = req.location();
154         try {
155                 SourceModel sm = sourceManager.sourceForLocation(loc);
156                 sm.showBreakpoint(loc.lineNumber(), true);
157                 showSourceForLocation(loc);
158             } catch (Exception JavaDoc exc) {
159             }
160     }
161
162         public void breakpointError(SpecErrorEvent e) {
163         breakpointDeleted(e);
164     }
165
166         public void watchpointSet(SpecEvent e) {
167         }
168         public void watchpointDeferred(SpecEvent e) {
169         }
170         public void watchpointDeleted(SpecEvent e) {
171         }
172         public void watchpointResolved(SpecEvent e) {
173         }
174         public void watchpointError(SpecErrorEvent e) {
175         }
176
177         public void exceptionInterceptSet(SpecEvent e) {
178         }
179         public void exceptionInterceptDeferred(SpecEvent e) {
180         }
181         public void exceptionInterceptDeleted(SpecEvent e) {
182         }
183         public void exceptionInterceptResolved(SpecEvent e) {
184         }
185         public void exceptionInterceptError(SpecErrorEvent e) {
186         }
187     }
188
189     private void showSourceContext(ThreadReference thread, int index) {
190     //### Should use ThreadInfo here.
191
StackFrame frame = null;
192     if (thread != null) {
193             try {
194                 frame = thread.frame(index);
195             } catch (IncompatibleThreadStateException e) {}
196         }
197     if (frame == null) {
198         return;
199     }
200     Location locn = frame.location();
201     /*****
202     if (!showSourceForLocation(locn)) {
203         env.notice("Could not display source for "
204                        + Utils.locationString(locn));
205     }
206     *****/

207     showSourceForLocation(locn);
208     }
209
210     public boolean showSourceForLocation(Location locn) {
211     sourceName = null;
212     sourceLocn = locn;
213     int lineNo = locn.lineNumber();
214     if (lineNo != -1) {
215         SourceModel source = sourceManager.sourceForLocation(locn);
216         if (source != null) {
217         showSourceAtLine(source, lineNo-1);
218         return true;
219         }
220     }
221     // Here if we could not display source.
222
showSourceUnavailable();
223     return false;
224     }
225
226     public boolean showSourceFile(String JavaDoc fileName) {
227     sourceLocn = null;
228     File file;
229     if (!fileName.startsWith(File.separator)) {
230         sourceName = fileName;
231         SearchPath sourcePath = sourceManager.getSourcePath();
232         file = sourcePath.resolve(fileName);
233         if (file == null) {
234         //env.failure("Source not found on current source path.");
235
showSourceUnavailable();
236         return false;
237         }
238     } else {
239         sourceName = null; // Absolute pathname does not depend on sourcepath.
240
file = new File(fileName);
241     }
242     SourceModel source = sourceManager.sourceForFile(file);
243     if (source != null) {
244         showSource(source);
245         return true;
246     }
247     showSourceUnavailable();
248     return false;
249     }
250
251     private void showSource(SourceModel model) {
252     setViewModel(model);
253     }
254
255     private void showSourceAtLine(SourceModel model, int lineNo) {
256     setViewModel(model);
257     if (model.isActuallySource && (lineNo < model.getSize())) {
258         list.setSelectedIndex(lineNo);
259             if (lineNo+4 < model.getSize()) {
260                 list.ensureIndexIsVisible(lineNo+4); // give some context
261
}
262         list.ensureIndexIsVisible(lineNo);
263     }
264     }
265
266     private void showSourceUnavailable() {
267     SourceModel model = new SourceModel("[Source code is not available]");
268     setViewModel(model);
269     }
270
271     private void setViewModel(SourceModel model) {
272     if (model != sourceModel) {
273         // install new model
274
list.setModel(model);
275         sourceModel = model;
276     }
277     }
278     
279     private class SourceLineRenderer extends DefaultListCellRenderer {
280     
281     public Component getListCellRendererComponent(JList list,
282                               Object JavaDoc value,
283                               int index,
284                               boolean isSelected,
285                               boolean cellHasFocus) {
286
287         //### Should set background highlight and/or icon if breakpoint on this line.
288
// Configures "this"
289
super.getListCellRendererComponent(list, value, index,
290                                                isSelected, cellHasFocus);
291
292             SourceModel.Line line = (SourceModel.Line)value;
293
294         //### Tab expansion is now done when source file is read in,
295
//### to speed up display. This costs a lot of space, slows
296
//### down source file loading, and has not been demonstrated
297
//### to yield an observable improvement in display performance.
298
//### Measurements may be appropriate here.
299
//String sourceLine = expandTabs((String)value);
300
setText(line.text);
301             if (line.hasBreakpoint) {
302                 setIcon(Icons.stopSignIcon);
303             } else if (line.isExecutable()) {
304                 setIcon(Icons.execIcon);
305             } else {
306                 setIcon(Icons.blankIcon);
307             }
308             
309
310         return this;
311     }
312
313         public Dimension getPreferredSize() {
314             Dimension dim = super.getPreferredSize();
315             return new Dimension(dim.width, dim.height-5);
316         }
317
318     }
319
320     private class STMouseListener extends MouseAdapter implements MouseListener {
321         public void mousePressed(MouseEvent e) {
322             if (e.isPopupTrigger()) {
323                 showPopupMenu((Component)e.getSource(),
324                               e.getX(), e.getY());
325             }
326         }
327
328         public void mouseReleased(MouseEvent e) {
329             if (e.isPopupTrigger()) {
330                 showPopupMenu((Component)e.getSource(),
331                               e.getX(), e.getY());
332             }
333         }
334
335         private void showPopupMenu(Component invoker, int x, int y) {
336             JList list = (JList)invoker;
337             int ln = list.getSelectedIndex() + 1;
338             SourceModel.Line line =
339                 (SourceModel.Line)list.getSelectedValue();
340             JPopupMenu popup = new JPopupMenu();
341
342             if (line == null) {
343                 popup.add(new JMenuItem("please select a line"));
344             } else if (line.isExecutable()) {
345                 String JavaDoc className = line.refType.name();
346                 if (line.hasBreakpoint()) {
347                     popup.add(commandItem("Clear Breakpoint",
348                                           "clear " + className +
349                                           ":" + ln));
350                 } else {
351                     popup.add(commandItem("Set Breakpoint",
352                                           "stop at " + className +
353                                           ":" + ln));
354                 }
355             } else {
356                 popup.add(new JMenuItem("not an executable line"));
357             }
358
359             popup.show(invoker,
360                        x + popup.getWidth()/2, y + popup.getHeight()/2);
361         }
362
363         private JMenuItem commandItem(String JavaDoc label, final String JavaDoc cmd) {
364             JMenuItem item = new JMenuItem(label);
365             item.addActionListener(new ActionListener() {
366                 public void actionPerformed(ActionEvent e) {
367                     interpreter.executeCommand(cmd);
368                 }
369             });
370             return item;
371         }
372     }
373 }
374
Popular Tags