/* * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ package sun.jvm.hotspot.ui; import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import sun.jvm.hotspot.CommandProcessor; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.utilities.*; /** A JPanel subclass containing a scrollable text area displaying the debugger's console, if it has one. This should not be created for a debugger which does not have a console. */ public class CommandProcessorPanel extends JPanel { private CommandProcessor commands; private JTextArea editor; private boolean updating; private int mark; private String curText; // handles multi-line input via '\' // Don't run the "main" method of this class unless this flag is set to true first private static final boolean DEBUGGING = false; ByteArrayOutputStream baos = new ByteArrayOutputStream(10240); public CommandProcessorPanel(CommandProcessor cp) { commands = cp; setLayout(new BorderLayout()); editor = new JTextArea(); editor.setDocument(new EditableAtEndDocument()); editor.setFont(GraphicsUtilities.lookupFont("Courier")); JScrollPane scroller = new JScrollPane(); scroller.getViewport().add(editor); add(scroller, BorderLayout.CENTER); // Set up out PrintStream o = new PrintStream(baos, true); cp.setOutput(o); cp.setErr(o); editor.getDocument().addDocumentListener(new DocumentListener() { public void changedUpdate(DocumentEvent e) { } public void insertUpdate(DocumentEvent e) { if (updating) return; beginUpdate(); editor.setCaretPosition(editor.getDocument().getLength()); if (insertContains(e, '\n')) { String cmd = getMarkedText(); // Handle multi-line input if ((cmd.length() == 0) || (cmd.charAt(cmd.length() - 1) != '\\')) { // Trim "\\n" combinations final String ln = trimContinuations(cmd); SwingUtilities.invokeLater(new Runnable() { public void run() { beginUpdate(); try { commands.executeCommand(ln, true); commands.printPrompt(); Document d = editor.getDocument(); try { d.insertString(d.getLength(), baos.toString(), null); } catch (BadLocationException ble) { ble.printStackTrace(); } baos.reset(); editor.setCaretPosition(editor.getDocument().getLength()); setMark(); } finally { endUpdate(); } } }); } } else { endUpdate(); } } public void removeUpdate(DocumentEvent e) { } }); // This is a bit of a hack but is probably better than relying on // the JEditorPane to update the caret's position precisely the // size of the insertion editor.addCaretListener(new CaretListener() { public void caretUpdate(CaretEvent e) { int len = editor.getDocument().getLength(); if (e.getDot() > len) { editor.setCaretPosition(len); } } }); Box hbox = Box.createHorizontalBox(); hbox.add(Box.createGlue()); JButton button = new JButton("Clear Saved Text"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { clear(); } }); hbox.add(button); hbox.add(Box.createGlue()); add(hbox, BorderLayout.SOUTH); clear(); } public void requestFocus() { editor.requestFocus(); } public void clear() { EditableAtEndDocument d = (EditableAtEndDocument) editor.getDocument(); d.clear(); commands.executeCommand("", false); setMark(); editor.requestFocus(); } public void setMark() { ((EditableAtEndDocument) editor.getDocument()).setMark(); } public String getMarkedText() { try { String s = ((EditableAtEndDocument) editor.getDocument()).getMarkedText(); int i = s.length(); while ((i > 0) && (s.charAt(i - 1) == '\n')) { i--; } return s.substring(0, i); } catch (BadLocationException e) { e.printStackTrace(); return null; } } //-------------------------------------------------------------------------------- // Internals only below this point // private void beginUpdate() { updating = true; } private void endUpdate() { updating = false; } private boolean insertContains(DocumentEvent e, char c) { String s = null; try { s = editor.getText(e.getOffset(), e.getLength()); for (int i = 0; i < e.getLength(); i++) { if (s.charAt(i) == c) { return true; } } } catch (BadLocationException ex) { ex.printStackTrace(); } return false; } private String trimContinuations(String text) { int i; while ((i = text.indexOf("\\\n")) >= 0) { text = text.substring(0, i) + text.substring(i+2, text.length()); } return text; } public static void main(String[] args) { JFrame frame = new JFrame(); frame.getContentPane().setLayout(new BorderLayout()); CommandProcessorPanel panel = new CommandProcessorPanel(null); frame.getContentPane().add(panel, BorderLayout.CENTER); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(500, 500); frame.setVisible(true); panel.requestFocus(); } }