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