Add debugger contribution from Christopher Oliver.

This commit is contained in:
nboyd%atg.com 2000-11-27 15:00:45 +00:00
Родитель 0167f0416d
Коммит e33e06b0e8
9 изменённых файлов: 6331 добавлений и 1 удалений

Просмотреть файл

@ -16,6 +16,8 @@ Requires Ant version 1.2
<property name="src.dir" value="."/>
<property name="src.examples" value="${src.dir}/examples"/>
<property name="src.debugger"
value="${src.dir}/org/mozilla/javascript/tools/debugger"/>
<property name="build.dir" value="./build"/>
<property name="build.dest" value="${build.dir}/classes"/>
@ -35,6 +37,8 @@ Requires Ant version 1.2
<property name="dist.docsrc.dir" value="${src.dir}/docs"/>
<available file="${cvs.javasrc.dir}/org" property="in-cvs-tree"/>
<available classname="com.ibm.bsf.BSFEngine" property="bsf.present"/>
<available file="${src.debugger}/AbstractCellEditor.java"
property="swing-ex-available"/>
</target>
<target name="init" depends="properties">
@ -50,7 +54,55 @@ Requires Ant version 1.2
<mkdir dir="${dist.apidocs}"/>
</target>
<target name="compile-from-cvs" if="in-cvs-tree" depends="prepare">
<target name="get-swing-ex" unless="swing-ex-available">
<!-- Download source from Sun's site, unzip it, remove
the files we don't need, and change the package
-->
<get src="http://java.sun.com/products/jfc/tsc/articles/treetable2/downloads/src.zip" dest="${build.dir}/swingExSrc.zip"/>
<unzip src="${build.dir}/swingExSrc.zip" dest="${src.debugger}"/>
<delete file="${src.debugger}/FileSystemModel2.java" />
<delete file="${src.debugger}/MergeSort.java" />
<delete file="${src.debugger}/TreeTableExample2.java" />
<replace file="${src.debugger}/AbstractCellEditor.java">
<replacetoken>import java.awt.Component;</replacetoken>
<replacevalue>
package org.mozilla.javascript.tools.debugger;
import java.awt.Component;
</replacevalue>
</replace>
<replace file="${src.debugger}/AbstractTreeTableModel.java">
<replacetoken>import javax.swing.tree.*;</replacetoken>
<replacevalue>
package org.mozilla.javascript.tools.debugger;
import javax.swing.tree.*;
</replacevalue>
</replace>
<replace file="${src.debugger}/JTreeTable.java">
<replacetoken>import javax.swing.*;</replacetoken>
<replacevalue>
package org.mozilla.javascript.tools.debugger;
import javax.swing.*;
</replacevalue>
</replace>
<replace file="${src.debugger}/TreeTableModel.java">
<replacetoken>import javax.swing.tree.TreeModel;</replacetoken>
<replacevalue>
package org.mozilla.javascript.tools.debugger;
import javax.swing.tree.TreeModel;
</replacevalue>
</replace>
<replace file="${src.debugger}/TreeTableModelAdapter.java">
<replacetoken>import javax.swing.JTree;</replacetoken>
<replacevalue>
package org.mozilla.javascript.tools.debugger;
import javax.swing.JTree;
</replacevalue>
</replace>
</target>
<target name="compile-from-cvs"
if="in-cvs-tree"
depends="prepare,get-swing-ex">
<javac srcdir="${cvs.javasrc.dir}"
destdir="${build.dest}"
includes="org/**/*.java"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,211 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Rhino JavaScript Debugger code, released
* November 21, 2000.
*
* The Initial Developer of the Original Code is See Beyond Corporation.
* Portions created by See Beyond are
* Copyright (C) 2000 See Beyond Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Christopher Oliver
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
package org.mozilla.javascript.tools.shell;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.text.Document;
import javax.swing.text.Segment;
public class JSConsole extends JFrame implements ActionListener {
private File CWD;
private JFileChooser dlg;
private ConsoleTextArea consoleTextArea;
public String chooseFile() {
if(CWD == null) {
String dir = System.getProperty("user.dir");
if(dir != null) {
CWD = new File(dir);
}
}
if(CWD != null) {
dlg.setCurrentDirectory(CWD);
}
dlg.setDialogTitle("Select a file to load");
int returnVal = dlg.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
String result = dlg.getSelectedFile().getPath();
CWD = dlg.getSelectedFile().getParentFile();
return result;
}
return null;
}
public static void main(String args[]) {
JSConsole console = new JSConsole(args);
}
public void createFileChooser() {
dlg = new JFileChooser();
javax.swing.filechooser.FileFilter filter =
new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
if(f.isDirectory()) {
return true;
}
String name = f.getName();
int i = name.lastIndexOf('.');
if(i > 0 && i < name.length() -1) {
String ext = name.substring(i + 1).toLowerCase();
if(ext.equals("js")) {
return true;
}
}
return false;
}
public String getDescription() {
return "JavaScript Files (*.js)";
}
};
dlg.addChoosableFileFilter(filter);
}
public JSConsole(String[] args) {
super("Rhino JavaScript Console");
JMenuBar menubar = new JMenuBar();
createFileChooser();
String[] fileItems = {"Load...", "Exit"};
String[] fileCmds = {"Load", "Exit"};
char[] fileShortCuts = {'L', 'X'};
String[] editItems = {"Cut", "Copy", "Paste"};
char[] editShortCuts = {'T', 'C', 'P'};
String[] plafItems = {"Metal", "Windows", "Motif"};
boolean [] plafState = {true, false, false};
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
JMenu editMenu = new JMenu("Edit");
editMenu.setMnemonic('E');
JMenu plafMenu = new JMenu("Platform");
plafMenu.setMnemonic('P');
for(int i = 0; i < fileItems.length; ++i) {
JMenuItem item = new JMenuItem(fileItems[i],
fileShortCuts[i]);
item.setActionCommand(fileCmds[i]);
item.addActionListener(this);
fileMenu.add(item);
}
for(int i = 0; i < editItems.length; ++i) {
JMenuItem item = new JMenuItem(editItems[i],
editShortCuts[i]);
item.addActionListener(this);
editMenu.add(item);
}
ButtonGroup group = new ButtonGroup();
for(int i = 0; i < plafItems.length; ++i) {
JRadioButtonMenuItem item = new JRadioButtonMenuItem(plafItems[i],
plafState[i]);
group.add(item);
item.addActionListener(this);
plafMenu.add(item);
}
menubar.add(fileMenu);
menubar.add(editMenu);
menubar.add(plafMenu);
setJMenuBar(menubar);
consoleTextArea = new ConsoleTextArea(args);
JScrollPane scroller = new JScrollPane(consoleTextArea);
setContentPane(scroller);
consoleTextArea.setRows(24);
consoleTextArea.setColumns(80);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
pack();
setVisible(true);
// System.setIn(consoleTextArea.getIn());
// System.setOut(consoleTextArea.getOut());
// System.setErr(consoleTextArea.getErr());
Main.setIn(consoleTextArea.getIn());
Main.setOut(consoleTextArea.getOut());
Main.setErr(consoleTextArea.getErr());
Main.main(args);
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String plaf_name = null;
if(cmd.equals("Load")) {
String f = chooseFile();
if(f != null) {
f = f.replace('\\', '/');
consoleTextArea.eval("load(\"" + f + "\");");
}
} else if(cmd.equals("Exit")) {
System.exit(0);
} else if(cmd.equals("Cut")) {
consoleTextArea.cut();
} else if(cmd.equals("Copy")) {
consoleTextArea.copy();
} else if(cmd.equals("Paste")) {
consoleTextArea.paste();
} else {
if(cmd.equals("Metal")) {
plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel";
} else if(cmd.equals("Windows")) {
plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
} else if(cmd.equals("Motif")) {
plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
}
if(plaf_name != null) {
try {
UIManager.setLookAndFeel(plaf_name);
SwingUtilities.updateComponentTreeUI(this);
consoleTextArea.postUpdateUI();
// updateComponentTreeUI seems to mess up the file
// chooser dialog, so just create a new one
createFileChooser();
} catch(Exception exc) {
JOptionPane.showMessageDialog(this,
exc.getMessage(),
"Platform",
JOptionPane.ERROR_MESSAGE);
}
}
}
}
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,418 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Rhino JavaScript Debugger code, released
* November 21, 2000.
*
* The Initial Developer of the Original Code is See Beyond Corporation.
* Portions created by See Beyond are
* Copyright (C) 2000 See Beyond Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Christopher Oliver
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
package org.mozilla.javascript.tools.debugger;
import java.io.File;
import java.util.Date;
import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.shell.Global;
import javax.swing.event.TableModelEvent;
import java.util.Hashtable;
import java.util.Enumeration;
public class VariableModel extends AbstractTreeTableModel
implements TreeTableModel {
// Names of the columns.
//static protected String[] cNames = {"Name", "Type", "Value"};
static protected String[] cNames = { " Name", " Value"};
// Types of the columns.
//static protected Class[] cTypes = {TreeTableModel.class, String.class, String.class};
static protected Class[] cTypes = {TreeTableModel.class, String.class};
public VariableModel(Scriptable scope) {
super(scope == null ? null : new VariableNode(scope, "this"));
}
//
// Some convenience methods.
//
protected Object getObject(Object node) {
VariableNode varNode = ((VariableNode)node);
if(varNode == null) return null;
return varNode.getObject();
}
protected Object[] getChildren(Object node) {
VariableNode varNode = ((VariableNode)node);
return varNode.getChildren();
}
//
// The TreeModel interface
//
public int getChildCount(Object node) {
Object[] children = getChildren(node);
return (children == null) ? 0 : children.length;
}
public Object getChild(Object node, int i) {
return getChildren(node)[i];
}
// The superclass's implementation would work, but this is more efficient.
public boolean isLeaf(Object node) {
if(node == null) return true;
VariableNode varNode = (VariableNode)node;
Object[] children = varNode.getChildren();
if(children != null && children.length > 0) {
return false;
}
//Object value = getObject(node);
//if(value != null && value instanceof Scriptable) {
//if(value == Undefined.instance ||
//value == ScriptableObject.NOT_FOUND) {
//return true;
//}
//Scriptable scrip = (Scriptable)value;
//Scriptable proto = scrip.getPrototype();
//if(proto != null &&
//proto != ScriptableObject.getObjectPrototype(scrip)) {
//return false;
//}
//}
// if(value == null) return true;
// if (value == Undefined.instance)
// return true;
// if (value == null)
// return true;
// if (value instanceof String)
// return true;
// if (value instanceof Number)
// return true;
// if (value instanceof Boolean)
// return true;
// if(value instanceof Scriptable) {
// //Scriptable scrip = (Scriptable)value;
//if(scrip.has(0, scrip)) {
//return false;
//}
//if(ScriptableObject.getPropertyIds(scrip).length > 0) {
//return false;
//}
//return true;
//}
return true;
}
public boolean isCellEditable(Object node, int column) {
return column == 0 || column == 2;
}
//
// The TreeTableNode interface.
//
public int getColumnCount() {
return cNames.length;
}
public String getColumnName(int column) {
return cNames[column];
}
public Class getColumnClass(int column) {
return cTypes[column];
}
public Object getValueAt(Object node, int column) {
Object value = getObject(node);
try {
switch(column) {
case 0: // Name
VariableNode varNode = (VariableNode)node;
String name = "";
if(varNode.name != null) {
return name + varNode.name;
}
return name + "[" + varNode.index + "]";
case -1: // Type
if(value == Undefined.instance || value == ScriptableObject.NOT_FOUND) {
return "undefined";
}
if (value == null)
return "object";
if (value instanceof Scriptable)
return (value instanceof Function) ? "function" : "object";
if (value instanceof String)
return "string";
if (value instanceof Number)
return "number";
if (value instanceof Boolean)
return "boolean";
return value.getClass().getName();
case 1: // value
if(value == Undefined.instance || value == ScriptableObject.NOT_FOUND) {
return "undefined";
}
if(value instanceof Scriptable) {
try {
Context cx = Context.enter();
String result;
try {
result = ScriptRuntime.toString(value);
} catch(Exception exc) {
result = value.toString();
} finally {
cx.exit();
}
StringBuffer buf = new StringBuffer();
int len = result.length();
for(int i = 0; i < len; i++) {
char ch = result.charAt(i);
if(Character.isISOControl(ch)) {
ch = ' ';
}
buf.append(ch);
}
return buf.toString();
} catch(Exception exc) {
exc.printStackTrace();
}
}
if(value == null) {
return "null";
}
return value.toString();
}
}
catch (Exception exc) {
//exc.printStackTrace();
}
return null;
}
public void setScope(Scriptable scope) {
//System.out.println("setScope: " + scope);
VariableNode rootVar = (VariableNode)root;
rootVar.scope = scope;
fireTreeNodesChanged(this,
new Object[]{root},
null, new Object[]{root});
}
}
class VariableNode {
Scriptable scope;
String name;
int index;
public VariableNode(Scriptable scope, String name) {
this.scope = scope;
this.name = name;
}
public VariableNode(Scriptable scope, int index) {
this.scope = scope;
this.name = null;
this.index = index;
}
/**
* Returns the the string to be used to display this leaf in the JTree.
*/
public String toString() {
return (name != null ? name : "[" + index + "]");
}
public Object getObject() {
try {
if(scope == null) return null;
if(name != null) {
if(name.equals("this")) {
return scope;
}
Object result;
if(name.equals("__proto__")) {
result = scope.getPrototype();
} else if(name.equals("__parent__")) {
result = scope.getParentScope();
} else {
result = scope.get(name, scope);
}
if(result == ScriptableObject.NOT_FOUND) {
result = Undefined.instance;
}
return result;
}
Object result = scope.get(index, scope);
if(result == ScriptableObject.NOT_FOUND) {
result = Undefined.instance;
}
return result;
} catch(Exception exc) {
return "undefined";
}
}
Object[] children;
/**
* Loads the children, caching the results in the children ivar.
*/
static final Object[] empty = new Object[0];
static Scriptable builtin[];
protected Object[] getChildren() {
if(children != null) return children;
try {
Object value = getObject();
if(value == null) return children = empty;
if(value == ScriptableObject.NOT_FOUND ||
value == Undefined.instance) {
return children = empty;
}
if(value instanceof Scriptable) {
Scriptable scrip = (Scriptable)value;
Scriptable proto = scrip.getPrototype();
Scriptable parent = scrip.getParentScope();
if(scrip instanceof NativeCall) {
parent = proto = null;
} else if(parent instanceof NativeCall) {
parent = null;
}
if(proto != null) {
if(builtin == null) {
builtin = new Scriptable[6];
builtin[0] =
ScriptableObject.getObjectPrototype(scrip);
builtin[1] =
ScriptableObject.getFunctionPrototype(scrip);
builtin[2] =
ScriptableObject.getClassPrototype(scrip,
"String");
builtin[3] =
ScriptableObject.getClassPrototype(scrip,
"Boolean");
builtin[4] =
ScriptableObject.getClassPrototype(scrip,
"Array");
builtin[5] =
ScriptableObject.getClassPrototype(scrip,
"Number");
}
for(int i = 0; i < builtin.length; i++) {
if(proto == builtin[i]) {
proto = null;
break;
}
}
}
if(scrip.has(0, scrip)) {
int len = 0;
try {
Scriptable start = scrip;
Scriptable obj = start;
Object result = Undefined.instance;
do {
if(obj.has("length", start)) {
result = obj.get("length", start);
if (result != Scriptable.NOT_FOUND)
break;
}
obj = obj.getPrototype();
} while (obj != null);
if(result instanceof Number) {
len = ((Number)result).intValue();
}
} catch(Exception exc) {
}
if(parent != null) {
len++;
}
if(proto != null) {
len++;
}
children = new VariableNode[len];
int i = 0;
int j = 0;
if(proto != null) {
children[i++] = new VariableNode(scrip, "__proto__");
j++;
}
if(parent != null) {
children[i++] = new VariableNode(scrip, "__parent__");
j++;
}
for(; i < len; i++) {
children[i] = new VariableNode(scrip, i-j);
}
} else {
int len = 0;
Hashtable t = new Hashtable();
Object[] ids = scrip.getIds();
if(proto != null) t.put("__proto__", "__proto__");
if(parent != null) t.put("__parent__", "__parent__");
if(ids.length > 0) {
for(int j = 0; j < ids.length; j++) {
t.put(ids[j], ids[j]);
}
}
ids = new Object[t.size()];
Enumeration e = t.keys();
int j = 0;
while(e.hasMoreElements()) {
ids[j++] = e.nextElement().toString();
}
if(ids != null && ids.length > 0) {
java.util.Arrays.sort(ids, new java.util.Comparator() {
public int compare(Object l, Object r) {
return l.toString().compareToIgnoreCase(r.toString());
}
});
len = ids.length;
}
children = new VariableNode[len];
for(int i = 0; i < len; i++) {
Object id = ids[i];
////System.out.println("id is " + id);
children[i] =
new VariableNode(scrip, id.toString());
}
}
}
} catch (Exception exc) {
exc.printStackTrace();
}
return children;
}
}

Просмотреть файл

@ -0,0 +1,296 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Rhino JavaScript Debugger code, released
* November 21, 2000.
*
* The Initial Developer of the Original Code is See Beyond Corporation.
* Portions created by See Beyond are
* Copyright (C) 2000 See Beyond Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Christopher Oliver
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
package org.mozilla.javascript.tools.shell;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.text.Document;
import javax.swing.text.Segment;
class ConsoleWrite implements Runnable {
private ConsoleTextArea textArea;
private String str;
public ConsoleWrite(ConsoleTextArea textArea, String str) {
this.textArea = textArea;
this.str = str;
}
public void run() {
textArea.write(str);
}
};
class ConsoleWriter extends java.io.OutputStream {
private ConsoleTextArea textArea;
private StringBuffer buffer;
public ConsoleWriter(ConsoleTextArea textArea) {
this.textArea = textArea;
buffer = new StringBuffer();
}
public synchronized void write(int ch) {
buffer.append((char)ch);
if(ch == '\n') {
flushBuffer();
}
}
public synchronized void write (char[] data, int off, int len) {
for(int i = off; i < len; i++) {
buffer.append(data[i]);
if(data[i] == '\n') {
flushBuffer();
}
}
}
public synchronized void flush() {
if (buffer.length() > 0) {
flushBuffer();
}
}
public void close () {
flush();
}
private void flushBuffer() {
String str = buffer.toString();
buffer.setLength(0);
SwingUtilities.invokeLater(new ConsoleWrite(textArea, str));
}
};
public class ConsoleTextArea extends JTextArea implements KeyListener,
DocumentListener {
private ConsoleWriter console1;
private ConsoleWriter console2;
private PrintStream out;
private PrintStream err;
private PrintWriter inPipe;
private PipedInputStream in;
private java.util.Vector history;
private int historyIndex = -1;
private int outputMark = 0;
public void select(int start, int end) {
requestFocus();
super.select(start, end);
}
public ConsoleTextArea(String[] argv) {
super();
history = new java.util.Vector();
console1 = new ConsoleWriter(this);
console2 = new ConsoleWriter(this);
out = new PrintStream(console1);
err = new PrintStream(console2);
PipedOutputStream outPipe = new PipedOutputStream();
inPipe = new PrintWriter(outPipe);
in = new PipedInputStream();
try {
outPipe.connect(in);
} catch(IOException exc) {
exc.printStackTrace();
}
getDocument().addDocumentListener(this);
addKeyListener(this);
setLineWrap(true);
setFont(new Font("Monospaced", 0, 12));
}
synchronized void returnPressed() {
Document doc = getDocument();
int len = doc.getLength();
Segment segment = new Segment();
try {
doc.getText(outputMark, len - outputMark, segment);
} catch(javax.swing.text.BadLocationException ignored) {
ignored.printStackTrace();
}
if(segment.count > 0) {
history.addElement(segment.toString());
}
historyIndex = history.size();
inPipe.write(segment.array, segment.offset, segment.count);
append("\n");
outputMark = doc.getLength();
inPipe.write("\n");
inPipe.flush();
console1.flush();
}
public void eval(String str) {
inPipe.write(str);
inPipe.write("\n");
inPipe.flush();
console1.flush();
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
if(outputMark == getCaretPosition()) {
e.consume();
}
} else if(code == KeyEvent.VK_HOME) {
int caretPos = getCaretPosition();
if(caretPos == outputMark) {
e.consume();
} else if(caretPos > outputMark) {
if(!e.isControlDown()) {
if(e.isShiftDown()) {
moveCaretPosition(outputMark);
} else {
setCaretPosition(outputMark);
}
e.consume();
}
}
} else if(code == KeyEvent.VK_ENTER) {
returnPressed();
e.consume();
} else if(code == KeyEvent.VK_UP) {
historyIndex--;
if(historyIndex >= 0) {
if(historyIndex >= history.size()) {
historyIndex = history.size() -1;
}
if(historyIndex >= 0) {
String str = (String)history.elementAt(historyIndex);
int len = getDocument().getLength();
replaceRange(str, outputMark, len);
int caretPos = outputMark + str.length();
select(caretPos, caretPos);
} else {
historyIndex++;
}
} else {
historyIndex++;
}
e.consume();
} else if(code == KeyEvent.VK_DOWN) {
int caretPos = outputMark;
if(history.size() > 0) {
historyIndex++;
if(historyIndex < 0) {historyIndex = 0;}
int len = getDocument().getLength();
if(historyIndex < history.size()) {
String str = (String)history.elementAt(historyIndex);
replaceRange(str, outputMark, len);
caretPos = outputMark + str.length();
} else {
historyIndex = history.size();
replaceRange("", outputMark, len);
}
}
select(caretPos, caretPos);
e.consume();
}
}
public void keyTyped(KeyEvent e) {
int keyChar = e.getKeyChar();
if(keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */) {
if(outputMark == getCaretPosition()) {
e.consume();
}
} else if(getCaretPosition() < outputMark) {
setCaretPosition(outputMark);
}
}
public synchronized void keyReleased(KeyEvent e) {
}
public synchronized void write(String str) {
insert(str, outputMark);
int len = str.length();
outputMark += len;
select(outputMark, outputMark);
}
public synchronized void insertUpdate(DocumentEvent e) {
int len = e.getLength();
int off = e.getOffset();
if(outputMark > off) {
outputMark += len;
}
}
public synchronized void removeUpdate(DocumentEvent e) {
int len = e.getLength();
int off = e.getOffset();
if(outputMark > off) {
if(outputMark >= off + len) {
outputMark -= len;
} else {
outputMark = off;
}
}
}
public synchronized void postUpdateUI() {
// this attempts to cleanup the damage done by updateComponentTreeUI
requestFocus();
setCaret(getCaret());
select(outputMark, outputMark);
}
public synchronized void changedUpdate(DocumentEvent e) {
}
public InputStream getIn() {
return in;
}
public PrintStream getOut() {
return out;
}
public PrintStream getErr() {
return err;
}
};

Просмотреть файл

@ -0,0 +1,211 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Rhino JavaScript Debugger code, released
* November 21, 2000.
*
* The Initial Developer of the Original Code is See Beyond Corporation.
* Portions created by See Beyond are
* Copyright (C) 2000 See Beyond Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Christopher Oliver
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
package org.mozilla.javascript.tools.shell;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.text.Document;
import javax.swing.text.Segment;
public class JSConsole extends JFrame implements ActionListener {
private File CWD;
private JFileChooser dlg;
private ConsoleTextArea consoleTextArea;
public String chooseFile() {
if(CWD == null) {
String dir = System.getProperty("user.dir");
if(dir != null) {
CWD = new File(dir);
}
}
if(CWD != null) {
dlg.setCurrentDirectory(CWD);
}
dlg.setDialogTitle("Select a file to load");
int returnVal = dlg.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
String result = dlg.getSelectedFile().getPath();
CWD = dlg.getSelectedFile().getParentFile();
return result;
}
return null;
}
public static void main(String args[]) {
JSConsole console = new JSConsole(args);
}
public void createFileChooser() {
dlg = new JFileChooser();
javax.swing.filechooser.FileFilter filter =
new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
if(f.isDirectory()) {
return true;
}
String name = f.getName();
int i = name.lastIndexOf('.');
if(i > 0 && i < name.length() -1) {
String ext = name.substring(i + 1).toLowerCase();
if(ext.equals("js")) {
return true;
}
}
return false;
}
public String getDescription() {
return "JavaScript Files (*.js)";
}
};
dlg.addChoosableFileFilter(filter);
}
public JSConsole(String[] args) {
super("Rhino JavaScript Console");
JMenuBar menubar = new JMenuBar();
createFileChooser();
String[] fileItems = {"Load...", "Exit"};
String[] fileCmds = {"Load", "Exit"};
char[] fileShortCuts = {'L', 'X'};
String[] editItems = {"Cut", "Copy", "Paste"};
char[] editShortCuts = {'T', 'C', 'P'};
String[] plafItems = {"Metal", "Windows", "Motif"};
boolean [] plafState = {true, false, false};
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
JMenu editMenu = new JMenu("Edit");
editMenu.setMnemonic('E');
JMenu plafMenu = new JMenu("Platform");
plafMenu.setMnemonic('P');
for(int i = 0; i < fileItems.length; ++i) {
JMenuItem item = new JMenuItem(fileItems[i],
fileShortCuts[i]);
item.setActionCommand(fileCmds[i]);
item.addActionListener(this);
fileMenu.add(item);
}
for(int i = 0; i < editItems.length; ++i) {
JMenuItem item = new JMenuItem(editItems[i],
editShortCuts[i]);
item.addActionListener(this);
editMenu.add(item);
}
ButtonGroup group = new ButtonGroup();
for(int i = 0; i < plafItems.length; ++i) {
JRadioButtonMenuItem item = new JRadioButtonMenuItem(plafItems[i],
plafState[i]);
group.add(item);
item.addActionListener(this);
plafMenu.add(item);
}
menubar.add(fileMenu);
menubar.add(editMenu);
menubar.add(plafMenu);
setJMenuBar(menubar);
consoleTextArea = new ConsoleTextArea(args);
JScrollPane scroller = new JScrollPane(consoleTextArea);
setContentPane(scroller);
consoleTextArea.setRows(24);
consoleTextArea.setColumns(80);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
pack();
setVisible(true);
// System.setIn(consoleTextArea.getIn());
// System.setOut(consoleTextArea.getOut());
// System.setErr(consoleTextArea.getErr());
Main.setIn(consoleTextArea.getIn());
Main.setOut(consoleTextArea.getOut());
Main.setErr(consoleTextArea.getErr());
Main.main(args);
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String plaf_name = null;
if(cmd.equals("Load")) {
String f = chooseFile();
if(f != null) {
f = f.replace('\\', '/');
consoleTextArea.eval("load(\"" + f + "\");");
}
} else if(cmd.equals("Exit")) {
System.exit(0);
} else if(cmd.equals("Cut")) {
consoleTextArea.cut();
} else if(cmd.equals("Copy")) {
consoleTextArea.copy();
} else if(cmd.equals("Paste")) {
consoleTextArea.paste();
} else {
if(cmd.equals("Metal")) {
plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel";
} else if(cmd.equals("Windows")) {
plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
} else if(cmd.equals("Motif")) {
plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
}
if(plaf_name != null) {
try {
UIManager.setLookAndFeel(plaf_name);
SwingUtilities.updateComponentTreeUI(this);
consoleTextArea.postUpdateUI();
// updateComponentTreeUI seems to mess up the file
// chooser dialog, so just create a new one
createFileChooser();
} catch(Exception exc) {
JOptionPane.showMessageDialog(this,
exc.getMessage(),
"Platform",
JOptionPane.ERROR_MESSAGE);
}
}
}
}
};