Mozilla/mozilla/js/rhino/docs/scriptjava.html
nboyd%atg.com 44b55e86b8 Update from mozilla-org
git-svn-id: svn://10.0.0.236/trunk@215435 18797224-902f-48f8-a5cc-f745e15eee43
2006-11-18 21:39:12 +00:00

306 lines
11 KiB
HTML

<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla 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/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (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
- MPL, indicate your decision by deleting the provisions above and replacing
- 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 MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta name="Author" content="Norris Boyd">
<meta name="KeyWords" content="Rhino, JavaScript, Java">
<title>Scripting Java</title>
<link rel="up" href="./" title="Rhino project page">
<link rel="section" href="#rhinoshell" title="Rhino Shell">
<link rel="section" href="#liveconnect" title="LiveConnect">
<link rel="section" href="#accessing" title="Accessing JavaBean">
<link rel="section" href="#importingclasses" title="Importing classes &amp; packages">
<link rel="section" href="#extending" title="Extending Java Classes">
<link rel="section" href="#javaadapter" title="JavaAdapter constructor">
</head>
<body>
<p class="crumbs"><em>You are here:</em> <a href="./">Rhino project page</a> &gt; <strong>Scripting Java</strong></p>
<h1 style="text-align: center;">Scripting Java</h1>
<address class="author">Norris Boyd</address>
<p>It's possible to use Rhino just for scripting Java. You don't have to
write any additional Java code; just use the existing Rhino shell and then
make calls into Java.</p>
<h2><a name="rhinoshell" id="rhinoshell">Rhino Shell</a></h2>
<p>The Rhino shell allows you to run scripts from files or interactively at
a command line.</p>
<p>If you download the zip file for rhino, it will contain a single JAR
file, <code class="filename">js.jar</code>. If you add the JAR file to
your class path, you can start the Rhino shell using the command</p>
<pre class="code"> java org.mozilla.javascript.tools.shell.Main
</pre>
<p>or if you have Java 2 (JDK 1.2 or greater), you can avoid changing your
classpath and simply use the command</p>
<pre class="code"> java -jar js.jar</pre>
<p>Unfortunately the <code>-jar</code> option to <code class="command">java</code>
will overwrite your existing classpath. The shell's interactive mode
is a good way to begin exploring Rhino.</p>
<p class="note">Earlier versions of Rhino have two JAR files, js.jar and
jstools.jar, and don't support the -jar option. Both JAR files must be
added to the class path to start the shell.</p>
<p>You can execute a JavaScript file by putting the file name as an argument
to the shell class:</p>
<pre> java org.mozilla.javascript.tools.shell.Main myScript.js</pre>
<p>There are a number of options for evaluating scripts using the shell. See
the <a href="shell.html">command description</a> for more information.</p>
<h2><a name="liveconnect" id="liveconnect">LiveConnect: Communicating with Java
from JavaScript</a></h2>
<p>If you are planning to script Java using Rhino, you'll want to use
LiveConnect, which allows you to create Java classes and call Java methods
from within JavaScript. For example, here's a log from an interactive session.
If you type it in, you'll see a window with a button filling it.</p>
<div class="figure" style="text-align: center;"><img src="scriptjavaframe.jpg" height="100" width="200" alt=""><br>
A Java frame created from the Rhino shell.</div>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js> importPackage(java.awt);
js> frame = new Frame("JavaScript")
java.awt.Frame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,resizable,title=JavaScript]
js> frame.show()
js> frame.setSize(new Dimension(200,100))
js> button = new Button("OK")
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js> frame.add(button)
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js> frame.show()
js> quit()
$
</pre>
<p>If you wish to load classes from JavaScript that aren't in the
<code>java</code> package, you'll need to prefix the package name
with "<code>Packages.</code>". For example:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; cx = Packages.org.mozilla.javascript.Context.currentContext
org.mozilla.javascript.Context@25980b44
js&gt; cx.evaluateString(this, "3+2", null, 0, null)
5.0
js&gt; quit()
$
</pre>
<h2><a name="accessing" id="accessing">Accessing JavaBean Properties</a></h2>
<p>Java classes can define JavaBean properties using getter and setter methods.
For example, the following class defines two properties:</p>
<pre class="code">
public class Me {
public int getAge() { return age; }
public void setAge(int anAge) { age = anAge;
}
public String getSex() { return "male"; }
private int age;
};
</pre>
<p>The two properties defined are <var>age</var> and <var>sex</var>.
The <var>sex</var> property is read-only: it has no setter.</p>
<p>Using Rhino we can access the bean properties as if they where
JavaScript properties. We can also continue to call the methods that
define the property.</p>
<pre class="code">
js&gt; me = new Packages.Me();
Me@93
js&gt; me.getSex()
male
js&gt; me.sex
male
js&gt; me.age = 33;
33
js&gt; me.age
33
js&gt; me.getAge()
33
js&gt;
</pre>
<p>Since the <var>sex</var> property is read-only, we are not allowed to write
to it.</p>
<p class="note">JavaBean reflection is not available in versions of Rhino before
1.5.</p>
<h2><a name="importingclasses" id="importingclasses">Importing Java Classes
and Packages</a></h2>
<p>Above we saw the use of the <code>importPackage</code> function
to import all the classes from a particular Java package. There is
also <code>importClass</code>, which imports a single class:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; importClass(Packages.org.mozilla.javascript.Context)
js&gt; cx = Context.enter()
org.mozilla.javascript.Context@25980d62
js&gt; cx.evaluateString(this, "3+2", null, 0, null)
5.0
js&gt; quit()
$
</pre>
<h2><a name="extending" id="extending">Extending Java Classes and
Implementing Java Interfaces with JavaScript</a></h2>
<p>Starting from the example above of creating a Java frame using JavaScript,
we can add a listener for the button. Once we call <code>addActionListener</code>
we can then click on the button to get the current date printed out:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; importPackage(java.awt);
js&gt; frame = new Frame("JavaScript")
java.awt.Frame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,resizable,title=JavaScript]
js&gt; button = new Button("OK")
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js&gt; frame.setSize(new Dimension(200,100))
js&gt; frame.add(button)
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js&gt; frame.show()
js&gt; function printDate() { print(new Date()) }
js&gt; printDate()
Wed Mar 15 15:42:20 GMT-0800 (PST) 2000
js&gt; o = { actionPerformed: printDate }
[object Object]
js&gt; o.actionPerformed()
Wed Mar 15 15:42:39 GMT-0800 (PST) 2000
js&gt; buttonListener = java.awt.event.ActionListener(o)
adapter0@6acc0f66
js&gt; button.addActionListener(buttonListener)
js&gt; Wed Mar 15 15:43:05 GMT-0800 (PST) 2000
Wed Mar 15 15:43:05 GMT-0800 (PST) 2000
Wed Mar 15 15:43:08 GMT-0800 (PST) 2000
quit()
$
</pre>
<p>When we type
<code class="command">buttonListener = java.awt.event.ActionListener(o)</code>,
Rhino actually creates a new Java class that implements
<code>ActionListener</code> and forwards calls from that class to
the JavaScript object. So when you click on the button, the
<code>printDate</code> method is called.</p>
<p>Starting from the release 1.5R5 Rhino allows to pass
JavaScript functions directly to Java methods if the corresponding
argument is Java interface and it either has the single method
or all its methods has the same number of arguments and
corresponding arguments has the same types. It allows to pass
<code>printDate</code> directly to <code>addActionListener</code>
and simplifies example:</p>
<pre class="code">
$ java org.mozilla.javascript.tools.shell.Main
js&gt; importPackage(java.awt);
js&gt; frame = new Frame("JavaScript")
java.awt.Frame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,title=JavaScript,resizable,normal]
js&gt; button = new Button("OK")
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js&gt; frame.setSize(new Dimension(200,100))
js&gt; frame.add(button)
java.awt.Button[button0,0,0,0x0,invalid,label=OK]
js> frame.show()
js&gt; function printDate() { print(new Date()) }
js&gt; printDate()
Mon Oct 27 2003 10:35:44 GMT+0100 (CET)
js&gt; button.addActionListener(printDate)
js&gt; Mon Oct 27 2003 10:36:09 GMT+0100 (CET)
Mon Oct 27 2003 10:36:10 GMT+0100 (CET)
quit()
$
</pre>
<h2><a name="javaadapter" id="javaadapter">JavaAdapter constructor</a></h2>
<p>Another way to create a JavaAdapter is to call the JavaAdapter constructor
explicitly. Using the JavaAdapter constructor gives you additional features
that cannot be had by "constructing" a Java interface as was done above.</p>
<p>Instead of writing</p>
<pre class="code">buttonListener = java.awt.event.ActionListener(o)
</pre>
<p>above we can also write</p>
<pre class="code">
buttonListener = new JavaAdapter(java.awt.event.ActionListener, o)
</pre>
<p>which is equivalent. If we also wanted to extend class <code>Foo</code>,
while also implementing <code>java.lang.Runnable</code>, we would write</p>
<pre class="code">
buttonListener = new JavaAdapter(Packages.Foo,
java.awt.event.ActionListener,
java.lang.Runnable, o)
</pre>
<p>In general the syntax is</p>
<pre class="code">
new JavaAdapter(<var>java-class</var>, [<var>java-class</var>,...] <var>javascript-object</var>)
</pre>
<p>where at most one <code>java-class</code> is a Java class and the
remaining <code>java-class</code>es are interfaces. The result will be
a Java adapter that extends any specified Java class, implements the
Java interfaces, and forwards any calls to the methods of the
<i>javascript-object</i>.</p>
</body>
</html>