Mercurial > hg > graal-jvmci-8
annotate agent/src/share/classes/sun/jvm/hotspot/ui/SourceCodePanel.java @ 14223:de6a9e811145
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
Summary: Copyright year updated for files modified during 2013
Reviewed-by: twisti, iveresov
author | mikael |
---|---|
date | Tue, 24 Dec 2013 11:48:39 -0800 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.ui; | |
26 | |
27 import java.awt.*; | |
28 import java.awt.event.*; | |
29 import java.io.*; | |
30 import java.net.*; | |
31 import java.util.*; | |
32 import javax.swing.*; | |
33 import javax.swing.text.BadLocationException; | |
34 | |
35 /** Panel supporting loading of and scrolling through source code. | |
36 Contains convenience routines for implementing the Editor | |
37 interface. */ | |
38 | |
39 public class SourceCodePanel extends JPanel { | |
40 private JTextArea source; | |
41 private RowHeader header; | |
42 private String filename; | |
43 // Amount of white space between edges, line numbers and icons | |
44 private static final int LINE_NO_SPACE = 4; | |
45 // Size of icons in resources directory | |
46 private static final int ICON_SIZE = 12; | |
47 // Icons used in panel drawing | |
48 private static Icon topFrameCurLine; | |
49 private static Icon lowerFrameCurLine; | |
50 private static Icon breakpoint; | |
51 // State | |
52 private int highlightedLine = -1; | |
53 private Set/*<Integer>*/ breakpoints = new HashSet(); // Zero-based lines internally | |
54 // Parent Editor container and EditorCommands object for setting breakpoints | |
55 private EditorCommands comm; | |
56 private Editor parent; | |
57 | |
58 /** Support for displaying icons and line numbers in row header of | |
59 scroll pane */ | |
60 class RowHeader extends JPanel { | |
61 private JViewport view; | |
62 private boolean showLineNumbers; | |
63 private int width; | |
64 private int rowHeight; | |
65 private boolean initted; | |
66 | |
67 public RowHeader() { | |
68 super(); | |
69 initted = true; | |
70 addHierarchyBoundsListener(new HierarchyBoundsAdapter() { | |
71 public void ancestorResized(HierarchyEvent e) { | |
72 recomputeSize(); | |
73 } | |
74 }); | |
75 } | |
76 | |
77 public void paint(Graphics g) { | |
78 super.paint(g); | |
79 if (getShowLineNumbers()) { | |
80 // Visible region of header panel, in coordinate system of the | |
81 // panel, is provided by clip bounds of Graphics object. This | |
82 // is used to figure out which line numbers to draw. | |
83 Rectangle clip = g.getClipBounds(); | |
84 // To avoid missing lines, round down starting line number and | |
85 // round up ending line number | |
86 int start = clip.y / rowHeight; | |
87 int end = start + (clip.height + (rowHeight - 1)) / rowHeight; | |
88 // Draw these line numbers, right justified to look better | |
89 FontMetrics fm = getFontMetrics(getFont()); | |
90 int ascent = fm.getMaxAscent(); // Causes proper alignment -- trial-and-error | |
91 for (int i = start; i <= end; i++) { | |
92 // Line numbers are 1-based | |
93 String str = Integer.toString(i + 1); | |
94 int strWidth = GraphicsUtilities.getStringWidth(str, fm); | |
95 g.drawString(str, width - strWidth - LINE_NO_SPACE, ascent + rowHeight * i); | |
96 | |
97 // Draw breakpoint if necessary | |
98 if (breakpoints.contains(new Integer(i))) { | |
99 breakpoint.paintIcon(this, g, LINE_NO_SPACE, rowHeight * i); | |
100 } | |
101 | |
102 // Draw current line icon if necessary | |
103 if (i == highlightedLine) { | |
104 // FIXME: use correct icon (not always topmost frame) | |
105 topFrameCurLine.paintIcon(this, g, LINE_NO_SPACE, rowHeight * i); | |
106 } | |
107 } | |
108 } | |
109 } | |
110 | |
111 public boolean getShowLineNumbers() { | |
112 return showLineNumbers; | |
113 } | |
114 | |
115 public void setShowLineNumbers(boolean val) { | |
116 if (val != showLineNumbers) { | |
117 showLineNumbers = val; | |
118 recomputeSize(); | |
119 // Force re-layout | |
120 invalidate(); | |
121 validate(); | |
122 } | |
123 } | |
124 | |
125 public void setFont(Font f) { | |
126 super.setFont(f); | |
127 rowHeight = getFontMetrics(f).getHeight(); | |
128 recomputeSize(); | |
129 } | |
130 | |
131 void setViewport(JViewport view) { | |
132 this.view = view; | |
133 } | |
134 | |
135 void recomputeSize() { | |
136 if (!initted) return; | |
137 if (view == null) return; | |
138 width = ICON_SIZE + 2 * LINE_NO_SPACE; | |
139 try { | |
140 int numLines = 1 + source.getLineOfOffset(source.getDocument().getEndPosition().getOffset() - 1); | |
141 String str = Integer.toString(numLines); | |
142 if (getShowLineNumbers()) { | |
143 // Compute width based on whether we are drawing line numbers | |
144 width += GraphicsUtilities.getStringWidth(str, getFontMetrics(getFont())) + LINE_NO_SPACE; | |
145 } | |
146 // FIXME: add on width for all icons (breakpoint, current line, | |
147 // current line in caller frame) | |
148 Dimension d = new Dimension(width, numLines * getFontMetrics(getFont()).getHeight()); | |
149 setSize(d); | |
150 setPreferredSize(d); | |
151 } catch (BadLocationException e) { | |
152 e.printStackTrace(); | |
153 } | |
154 } | |
155 } | |
156 | |
157 public SourceCodePanel() { | |
158 maybeLoadIcons(); | |
159 | |
160 // Build user interface | |
161 setLayout(new BorderLayout()); | |
162 source = new JTextArea(); | |
163 source.setEditable(false); | |
164 source.getCaret().setVisible(true); | |
165 header = new RowHeader(); | |
166 header.setShowLineNumbers(true); | |
167 JScrollPane scroller = new JScrollPane(source); | |
168 JViewport rowView = new JViewport(); | |
169 rowView.setView(header); | |
170 header.setViewport(rowView); | |
171 rowView.setScrollMode(JViewport.SIMPLE_SCROLL_MODE); | |
172 scroller.setRowHeader(rowView); | |
173 add(scroller, BorderLayout.CENTER); | |
174 // Reset font now that header and source are present | |
175 setFont(getFont()); | |
176 | |
177 source.addFocusListener(new FocusAdapter() { | |
178 public void focusGained(FocusEvent e) { | |
179 source.getCaret().setVisible(true); | |
180 } | |
181 }); | |
182 | |
183 source.addKeyListener(new KeyAdapter() { | |
184 public void keyPressed(KeyEvent e) { | |
185 if (e.getKeyCode() == KeyEvent.VK_F9) { | |
186 int lineNo = getCurrentLineNumber(); | |
187 // Only the debugger can figure out whether we are setting | |
188 // or clearing a breakpoint, since it has the debug | |
189 // information available and knows whether we're on a | |
190 // valid line | |
191 comm.toggleBreakpointAtLine(parent, lineNo); | |
192 } | |
193 } | |
194 }); | |
195 | |
196 } | |
197 | |
198 public void setFont(Font f) { | |
199 super.setFont(f); | |
200 if (source != null) { | |
201 source.setFont(f); | |
202 } | |
203 if (header != null) { | |
204 header.setFont(f); | |
205 } | |
206 } | |
207 | |
208 public boolean getShowLineNumbers() { | |
209 return header.getShowLineNumbers(); | |
210 } | |
211 | |
212 public void setShowLineNumbers(boolean val) { | |
213 header.setShowLineNumbers(val); | |
214 } | |
215 | |
216 public boolean openFile(String filename) { | |
217 try { | |
218 this.filename = filename; | |
219 File file = new File(filename); | |
220 int len = (int) file.length(); | |
221 StringBuffer buf = new StringBuffer(len); // Approximation | |
222 char[] tmp = new char[4096]; | |
223 FileReader in = new FileReader(file); | |
224 int res = 0; | |
225 do { | |
226 res = in.read(tmp, 0, tmp.length); | |
227 if (res >= 0) { | |
228 buf.append(tmp, 0, res); | |
229 } | |
230 } while (res != -1); | |
231 in.close(); | |
232 String text = buf.toString(); | |
233 source.setText(text); | |
234 header.recomputeSize(); | |
235 return true; | |
236 } catch (IOException e) { | |
237 return false; | |
238 } | |
239 } | |
240 | |
241 public String getSourceFileName() { | |
242 return filename; | |
243 } | |
244 | |
245 /** Line number is one-based */ | |
246 public int getCurrentLineNumber() { | |
247 try { | |
248 return 1 + source.getLineOfOffset(source.getCaretPosition()); | |
249 } catch (BadLocationException e) { | |
250 return 0; | |
251 } | |
252 } | |
253 | |
254 /** Line number is one-based */ | |
255 public void showLineNumber(int lineNo) { | |
256 try { | |
257 int offset = source.getLineStartOffset(lineNo - 1); | |
258 Rectangle rect = source.modelToView(offset); | |
259 if (rect == null) { | |
260 return; | |
261 } | |
262 source.scrollRectToVisible(rect); | |
263 } catch (BadLocationException e) { | |
264 e.printStackTrace(); | |
265 } | |
266 } | |
267 | |
268 /** Line number is one-based */ | |
269 public void highlightLineNumber(int lineNo) { | |
270 highlightedLine = lineNo - 1; | |
271 } | |
272 | |
273 public void showBreakpointAtLine(int lineNo) { breakpoints.add(new Integer(lineNo - 1)); repaint(); } | |
274 public boolean hasBreakpointAtLine(int lineNo){ return breakpoints.contains(new Integer(lineNo - 1)); } | |
275 public void clearBreakpointAtLine(int lineNo) { breakpoints.remove(new Integer(lineNo - 1)); repaint(); } | |
276 public void clearBreakpoints() { breakpoints.clear(); repaint(); } | |
277 | |
278 public void setEditorCommands(EditorCommands comm, Editor parent) { | |
279 this.comm = comm; | |
280 this.parent = parent; | |
281 } | |
282 | |
283 public void requestFocus() { | |
284 source.requestFocus(); | |
285 } | |
286 | |
287 //---------------------------------------------------------------------- | |
288 // Internals only below this point | |
289 // | |
290 | |
291 private void maybeLoadIcons() { | |
292 if (topFrameCurLine == null) { | |
293 topFrameCurLine = loadIcon("resources/arrow.png"); | |
294 lowerFrameCurLine = loadIcon("resources/triangle.png"); | |
295 breakpoint = loadIcon("resources/breakpoint.png"); | |
296 } | |
297 } | |
298 | |
299 private Icon loadIcon(String which) { | |
300 URL url = getClass().getResource(which); | |
301 return new ImageIcon(url); | |
302 } | |
303 } |