sourcetool.java
来自「jpda例子文件」· Java 代码 · 共 374 行
JAVA
374 行
/* * @(#)SourceTool.java 1.13 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */package com.sun.tools.example.debug.gui;import java.io.*;import java.util.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import com.sun.jdi.*;import com.sun.jdi.request.*;import com.sun.tools.example.debug.event.*;import com.sun.tools.example.debug.bdi.*;import java.util.List;public class SourceTool extends JPanel { private Environment env; private ExecutionManager runtime; private ContextManager context; private SourceManager sourceManager; private JList list; private ListModel sourceModel; // Information on source file that is on display, or failed to be // displayed due to inaccessible source. Used to update display // when sourcepath is changed. private String sourceName; // relative path name, if showSourceFile private Location sourceLocn; // location, if showSourceForLocation private CommandInterpreter interpreter; public SourceTool(Environment env) { super(new BorderLayout()); this.env = env; runtime = env.getExecutionManager(); sourceManager = env.getSourceManager(); this.context = env.getContextManager(); this.interpreter = new CommandInterpreter(env, true); sourceModel = new DefaultListModel(); // empty list = new JList(sourceModel); list.setCellRenderer(new SourceLineRenderer()); list.setPrototypeCellValue(SourceModel.prototypeCellValue); SourceToolListener listener = new SourceToolListener(); context.addContextListener(listener); runtime.addSpecListener(listener); sourceManager.addSourceListener(listener); MouseListener squeek = new STMouseListener(); list.addMouseListener(squeek); add(new JScrollPane(list)); } public void setTextFont(Font f) { list.setFont(f); list.setPrototypeCellValue(SourceModel.prototypeCellValue); } private class SourceToolListener implements ContextListener, SourceListener, SpecListener { // ContextListener public void currentFrameChanged(CurrentFrameChangedEvent e) { showSourceContext(e.getThread(), e.getIndex()); } // Clear source view. // sourceModel = new DefaultListModel(); // empty // SourceListener public void sourcepathChanged(SourcepathChangedEvent e) { // Reload source view if its contents depend // on the source path. if (sourceName != null) { showSourceFile(sourceName); } else if (sourceLocn != null) { showSourceForLocation(sourceLocn); } } // SpecListener public void breakpointSet(SpecEvent e) { breakpointResolved(e); } public void breakpointDeferred(SpecEvent e) { } public void breakpointDeleted(SpecEvent e) { BreakpointRequest req = (BreakpointRequest)e.getEventRequest(); Location loc = req.location(); if (loc != null) { try { SourceModel sm = sourceManager.sourceForLocation(loc); sm.showBreakpoint(loc.lineNumber(), false); showSourceForLocation(loc); } catch (Exception exc) { } } } public void breakpointResolved(SpecEvent e) { BreakpointRequest req = (BreakpointRequest)e.getEventRequest(); Location loc = req.location(); try { SourceModel sm = sourceManager.sourceForLocation(loc); sm.showBreakpoint(loc.lineNumber(), true); showSourceForLocation(loc); } catch (Exception exc) { } } public void breakpointError(SpecErrorEvent e) { breakpointDeleted(e); } public void watchpointSet(SpecEvent e) { } public void watchpointDeferred(SpecEvent e) { } public void watchpointDeleted(SpecEvent e) { } public void watchpointResolved(SpecEvent e) { } public void watchpointError(SpecErrorEvent e) { } public void exceptionInterceptSet(SpecEvent e) { } public void exceptionInterceptDeferred(SpecEvent e) { } public void exceptionInterceptDeleted(SpecEvent e) { } public void exceptionInterceptResolved(SpecEvent e) { } public void exceptionInterceptError(SpecErrorEvent e) { } } private void showSourceContext(ThreadReference thread, int index) { //### Should use ThreadInfo here. StackFrame frame = null; if (thread != null) { try { frame = thread.frame(index); } catch (IncompatibleThreadStateException e) {} } if (frame == null) { return; } Location locn = frame.location(); /***** if (!showSourceForLocation(locn)) { env.notice("Could not display source for " + Utils.locationString(locn)); } *****/ showSourceForLocation(locn); } public boolean showSourceForLocation(Location locn) { sourceName = null; sourceLocn = locn; int lineNo = locn.lineNumber(); if (lineNo != -1) { SourceModel source = sourceManager.sourceForLocation(locn); if (source != null) { showSourceAtLine(source, lineNo-1); return true; } } // Here if we could not display source. showSourceUnavailable(); return false; } public boolean showSourceFile(String fileName) { sourceLocn = null; File file; if (!fileName.startsWith(File.separator)) { sourceName = fileName; SearchPath sourcePath = sourceManager.getSourcePath(); file = sourcePath.resolve(fileName); if (file == null) { //env.failure("Source not found on current source path."); showSourceUnavailable(); return false; } } else { sourceName = null; // Absolute pathname does not depend on sourcepath. file = new File(fileName); } SourceModel source = sourceManager.sourceForFile(file); if (source != null) { showSource(source); return true; } showSourceUnavailable(); return false; } private void showSource(SourceModel model) { setViewModel(model); } private void showSourceAtLine(SourceModel model, int lineNo) { setViewModel(model); if (model.isActuallySource && (lineNo < model.getSize())) { list.setSelectedIndex(lineNo); if (lineNo+4 < model.getSize()) { list.ensureIndexIsVisible(lineNo+4); // give some context } list.ensureIndexIsVisible(lineNo); } } private void showSourceUnavailable() { SourceModel model = new SourceModel("[Source code is not available]"); setViewModel(model); } private void setViewModel(SourceModel model) { if (model != sourceModel) { // install new model list.setModel(model); sourceModel = model; } } private class SourceLineRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { //### Should set background highlight and/or icon if breakpoint on this line. // Configures "this" super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); SourceModel.Line line = (SourceModel.Line)value; //### Tab expansion is now done when source file is read in, //### to speed up display. This costs a lot of space, slows //### down source file loading, and has not been demonstrated //### to yield an observable improvement in display performance. //### Measurements may be appropriate here. //String sourceLine = expandTabs((String)value); setText(line.text); if (line.hasBreakpoint) { setIcon(Icons.stopSignIcon); } else if (line.isExecutable()) { setIcon(Icons.execIcon); } else { setIcon(Icons.blankIcon); } return this; } public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); return new Dimension(dim.width, dim.height-5); } } private class STMouseListener extends MouseAdapter implements MouseListener { public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { showPopupMenu((Component)e.getSource(), e.getX(), e.getY()); } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { showPopupMenu((Component)e.getSource(), e.getX(), e.getY()); } } private void showPopupMenu(Component invoker, int x, int y) { JList list = (JList)invoker; int ln = list.getSelectedIndex() + 1; SourceModel.Line line = (SourceModel.Line)list.getSelectedValue(); JPopupMenu popup = new JPopupMenu(); if (line == null) { popup.add(new JMenuItem("please select a line")); } else if (line.isExecutable()) { String className = line.refType.name(); if (line.hasBreakpoint()) { popup.add(commandItem("Clear Breakpoint", "clear " + className + ":" + ln)); } else { popup.add(commandItem("Set Breakpoint", "stop at " + className + ":" + ln)); } } else { popup.add(new JMenuItem("not an executable line")); } popup.show(invoker, x + popup.getWidth()/2, y + popup.getHeight()/2); } private JMenuItem commandItem(String label, final String cmd) { JMenuItem item = new JMenuItem(label); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { interpreter.executeCommand(cmd); } }); return item; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?