blob: 0bf2d75deb1bcc5615c6325f401c9a9658aa16a0 [file] [log] [blame]
/*
* Copyright (c) 2000, 2008, 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.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
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 DebuggerConsolePanel extends JPanel {
private Debugger debugger;
private JTextComponent 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;
public DebuggerConsolePanel(Debugger debugger) {
this.debugger = debugger;
if (!DEBUGGING) {
if (Assert.ASSERTS_ENABLED) {
Assert.that(debugger.hasConsole(), "should not create a DebuggerConsolePanel for non-console debuggers");
}
}
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);
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
cmd = trimContinuations(cmd);
final String result;
if (DEBUGGING) {
System.err.println("Entered command: \"" + cmd + "\"");
result = "";
} else {
result = DebuggerConsolePanel.this.debugger.consoleExecuteCommand(cmd);
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
print(result);
printPrompt();
setMark();
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();
printPrompt();
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 void print(String s) {
Document d = editor.getDocument();
try {
d.insertString(d.getLength(), s, null);
}
catch (BadLocationException e) {
e.printStackTrace();
}
}
private void printPrompt() {
if (DEBUGGING) {
print("foo> ");
} else {
print(debugger.getConsolePrompt());
}
}
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());
DebuggerConsolePanel panel = new DebuggerConsolePanel(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();
}
}