1/* 2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 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 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25package sun.jvm.hotspot.ui; 26 27import java.awt.*; 28import java.awt.event.*; 29import javax.swing.*; 30import javax.swing.event.*; 31import javax.swing.text.*; 32 33import sun.jvm.hotspot.debugger.*; 34import sun.jvm.hotspot.utilities.*; 35 36/** A JPanel subclass containing a scrollable text area displaying the 37 debugger's console, if it has one. This should not be created for 38 a debugger which does not have a console. */ 39 40public class DebuggerConsolePanel extends JPanel { 41 private Debugger debugger; 42 private JTextComponent editor; 43 private boolean updating; 44 private int mark; 45 private String curText; // handles multi-line input via '\' 46 // Don't run the "main" method of this class unless this flag is set to true first 47 private static final boolean DEBUGGING = false; 48 49 public DebuggerConsolePanel(Debugger debugger) { 50 this.debugger = debugger; 51 if (!DEBUGGING) { 52 if (Assert.ASSERTS_ENABLED) { 53 Assert.that(debugger.hasConsole(), "should not create a DebuggerConsolePanel for non-console debuggers"); 54 } 55 } 56 57 setLayout(new BorderLayout()); 58 59 editor = new JTextArea(); 60 editor.setDocument(new EditableAtEndDocument()); 61 editor.setFont(GraphicsUtilities.lookupFont("Courier")); 62 JScrollPane scroller = new JScrollPane(); 63 scroller.getViewport().add(editor); 64 add(scroller, BorderLayout.CENTER); 65 66 editor.getDocument().addDocumentListener(new DocumentListener() { 67 public void changedUpdate(DocumentEvent e) { 68 } 69 70 public void insertUpdate(DocumentEvent e) { 71 if (updating) return; 72 beginUpdate(); 73 editor.setCaretPosition(editor.getDocument().getLength()); 74 if (insertContains(e, '\n')) { 75 String cmd = getMarkedText(); 76 // Handle multi-line input 77 if ((cmd.length() == 0) || (cmd.charAt(cmd.length() - 1) != '\\')) { 78 // Trim "\\n" combinations 79 cmd = trimContinuations(cmd); 80 final String result; 81 if (DEBUGGING) { 82 System.err.println("Entered command: \"" + cmd + "\""); 83 result = ""; 84 } else { 85 result = DebuggerConsolePanel.this.debugger.consoleExecuteCommand(cmd); 86 } 87 88 SwingUtilities.invokeLater(new Runnable() { 89 public void run() { 90 print(result); 91 printPrompt(); 92 setMark(); 93 endUpdate(); 94 } 95 }); 96 } 97 } else { 98 endUpdate(); 99 } 100 } 101 102 public void removeUpdate(DocumentEvent e) { 103 } 104 }); 105 106 // This is a bit of a hack but is probably better than relying on 107 // the JEditorPane to update the caret's position precisely the 108 // size of the insertion 109 editor.addCaretListener(new CaretListener() { 110 public void caretUpdate(CaretEvent e) { 111 int len = editor.getDocument().getLength(); 112 if (e.getDot() > len) { 113 editor.setCaretPosition(len); 114 } 115 } 116 }); 117 118 Box hbox = Box.createHorizontalBox(); 119 hbox.add(Box.createGlue()); 120 JButton button = new JButton("Clear Saved Text"); 121 button.addActionListener(new ActionListener() { 122 public void actionPerformed(ActionEvent e) { 123 clear(); 124 } 125 }); 126 hbox.add(button); 127 hbox.add(Box.createGlue()); 128 add(hbox, BorderLayout.SOUTH); 129 130 clear(); 131 } 132 133 public void requestFocus() { 134 editor.requestFocus(); 135 } 136 137 public void clear() { 138 EditableAtEndDocument d = (EditableAtEndDocument) editor.getDocument(); 139 d.clear(); 140 printPrompt(); 141 setMark(); 142 editor.requestFocus(); 143 } 144 145 public void setMark() { 146 ((EditableAtEndDocument) editor.getDocument()).setMark(); 147 } 148 149 public String getMarkedText() { 150 try { 151 String s = ((EditableAtEndDocument) editor.getDocument()).getMarkedText(); 152 int i = s.length(); 153 while ((i > 0) && (s.charAt(i - 1) == '\n')) { 154 i--; 155 } 156 return s.substring(0, i); 157 } 158 catch (BadLocationException e) { 159 e.printStackTrace(); 160 return null; 161 } 162 } 163 164 //-------------------------------------------------------------------------------- 165 // Internals only below this point 166 // 167 168 private void beginUpdate() { 169 updating = true; 170 } 171 172 private void endUpdate() { 173 updating = false; 174 } 175 176 private void print(String s) { 177 Document d = editor.getDocument(); 178 try { 179 d.insertString(d.getLength(), s, null); 180 } 181 catch (BadLocationException e) { 182 e.printStackTrace(); 183 } 184 } 185 186 private void printPrompt() { 187 if (DEBUGGING) { 188 print("foo> "); 189 } else { 190 print(debugger.getConsolePrompt()); 191 } 192 } 193 194 private boolean insertContains(DocumentEvent e, char c) { 195 String s = null; 196 try { 197 s = editor.getText(e.getOffset(), e.getLength()); 198 for (int i = 0; i < e.getLength(); i++) { 199 if (s.charAt(i) == c) { 200 return true; 201 } 202 } 203 } 204 catch (BadLocationException ex) { 205 ex.printStackTrace(); 206 } 207 return false; 208 } 209 210 private String trimContinuations(String text) { 211 int i; 212 while ((i = text.indexOf("\\\n")) >= 0) { 213 text = text.substring(0, i) + text.substring(i+2, text.length()); 214 } 215 return text; 216 } 217 218 public static void main(String[] args) { 219 JFrame frame = new JFrame(); 220 frame.getContentPane().setLayout(new BorderLayout()); 221 DebuggerConsolePanel panel = new DebuggerConsolePanel(null); 222 frame.getContentPane().add(panel, BorderLayout.CENTER); 223 frame.addWindowListener(new WindowAdapter() { 224 public void windowClosing(WindowEvent e) { 225 System.exit(0); 226 } 227 }); 228 frame.setSize(500, 500); 229 frame.setVisible(true); 230 panel.requestFocus(); 231 } 232} 233