Tải bản đầy đủ (.pdf) (22 trang)

Using Java with JavaScript

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (255.74 KB, 22 trang )

Chapter 22. Using Java with
JavaScript
As we discussed in Chapter 14, Netscape 3 and later and Internet Explorer 4 and later
both allow JavaScript programs to read and write the public fields and invoke the public
methods of Java applets embedded in HTML documents. Netscape supports JavaScript
interaction with Java applets through a technology known as LiveConnect. Internet
Explorer instead treats every Java object (including applets) as an ActiveX control and
uses its ActiveX scripting technology to allow JavaScript programs to interact with Java.
Because Netscape's technology is specifically designed for communication between
JavaScript and Java, it has some features that IE's ActiveX technology cannot provide. In
practice, however, the two technologies are fairly compatible. Although this chapter is
based on Netscape's LiveConnect, the key features it describes work in IE as well.
[1]
[1]
Note that Netscape 6 was released with poor support for LiveConnect but that it is fully implemented in Netscape 6.1 and later.
This chapter begins with a discussion of how you can use JavaScript to script Java
applets, how your Java applets can invoke JavaScript code, and how (in Netscape only)
you can use JavaScript to work directly with Java system classes. It then documents the
nitty-gritty details of how LiveConnect works. It assumes you have at least a basic
familiarity with Java programming (see
Java in a Nutshell, by David Flanagan, and
Learning Java, by Patrick Niemeyer and Jonathan Knudsen, both published by O'Reilly).
22.1 Scripting Java Applets
As discussed in Chapter 14, all Java applets embedded in a web page become part of the
Document.applets[] array. Also, if given a name or id, an applet can be accessed
ple, the applet created by an
be referred to as document.chart.
cript as if they were
the properties and methods of a JavaScript object. For example, if an applet named
var chartcolor = document.chart.lineColor; // Read an applet field
document.chart.lineColor = "#ff00ff"; // Set an applet field


JavaScript can even query and set the values of fields that are arrays. Suppose that the
chart applet defines two fields declared as follows ( Java code):
public int numPoints;
public double[] points;
directly as a property of the Document object. For exam
<applet> tag with a name attribute of "chart" can
The public fields and methods of every applet are accessible to JavaS
"chart" defines a field named
lineColor whose type is String, a JavaScript program can
query and set this field with code like this:
A JavaScript program might use these fields with code like this:
for(var i = 0; i < document.chart.numPoints; i++)
document.chart.points[i] = i*i;
This example illustrates the tricky thing about connecting JavaScript and Java: type
conversion. Java is a strongly typed language with a fair number of distinct primitive
is converted to ber and various JavaScript
numbers are converted to Java double values. There is a lot of work going on behind the
scenes to ensure that these values are properly converted as needed. Later in this chapter,
we'll consider the topic of data type conversion in detail.
In addition to querying and setting the fields of a Java applet, JavaScript can also invoke
the methods of an applet. Suppose, for example, that the chart applet defines a method
named redraw( ). This method takes no arguments and simply serves to notify the
applet that its points[] array has been modified and it should redraw itself. JavaScript
can invoke this method just as if it was a JavaScript method:
onverting JavaScript
public void setDomain(double xmin, double xmax);
document.chart.setDomain(0, 20);
document.ch
var label = document.chart.getXAxisLabel( );
Finally, note that Java methods can return Java objects as their return values, and

JavaScript can read and write the public fields and invoke the public methods of these
objects as well. JavaScript can also use Java objects as arguments to Java methods.
uppose the Java applet defines a method named getXAxis( ) that returns a Java object
that is an instance of a class named Axis and a method named setYAxis( ) that takes an
has a method named
cript code like this:
types. JavaScript is loosely typed and has only a single numeric type. In the previous
example, a Java integer a JavaScript num
document.chart.redraw( );
JavaScript can also call methods that take arguments and return values. The underlying
LiveConnect or ActiveX scripting technology does the work of c
argument values into legal Java values and converting Java return values into legal
JavaScript values. Suppose the chart applet defines Java methods like these:
public void setChartTitle(String title);
public String getXAxisLabel( );
JavaScript can call these methods with code like this:
art.setChartTitle("y = x*x");
S
argument of the same type. Now, suppose further that Axis
setTitle( ). We might use these methods with JavaS
var xaxis = document.chart.getXAxis( ); // Get an Axis object
= xaxis.clone( ); // Make a copy of it
itle("Y"); // Call a method of it...
document.chart.setYAxis(newyaxis); // and pass it to another
method
There is one complication when we use JavaScript to invoke the methods of a Java
object. Java allows two or more methods to have the same name, as long as they have
different argument types. For example, a Java object could declare these two methods:
public String convert(int i); // Convert an integer to a string
public String convert(double d); // Convert a floating-point number

JavaScript has only one numeric type and doesn't distinguish between integers and
floating-point values, so when you use JavaScript to pass a number to the method named
"convert", it cannot tell which one you intended to call. In practice, this problem doesn't
arise often, and it is usually possible to work around it by simply renaming the methods
as needed. The latest versions of LiveConnect (in Netscape 6.1 and later) also allow you
to disambiguate cases like this by including the argument types in the method name. For
example, if the two methods above were defined by document.applets[0], you could
disambiguate them like this:
var iconvert = document.applets[0]["convert(int)"]; // Get int method
iconvert(3); // Invoke the method like this
ava
code, we now turn to the opposite
his control is accomplished
.1 The JSObject Class
All Java interactions with JavaScript are handled through an instance of the
netscape.javascript.JSObject class. An instance of this class is a wrapper around a single
JavaScript object. The class defines methods that allow you to read and write property
values and array elements of the JavaScript object and to invoke methods of the object.
Here is a synopsis of this class:
public final class JSObject extends Object {
var newyaxis
newyaxis.setT
22.2 Using JavaScript from J
Having explored how to control Java from JavaScript
problem: how to control JavaScript from Java code. T
primarily through the Java netscape.javascript.JSObject class, which represents a
JavaScript object within a Java program. The JavaScript-to-Java capabilities described in
the previous section typically work well in both Netscape and Internet Explorer. In
contrast, the Java-to-JavaScript techniques described here are not as robustly supported,
and you may well encounter bugs in both Netscape and IE.

22.2
// Static method to obtain initial JSObject for applet's browser
window
public static JSObject getWindow(java.applet.Applet applet);
public Object getMember(String name); // Read
object property
public Object getSlot(int index); // Read
array element
public void setMember(String name, Object value); // Set
object property
public void setSlot(int index, Object value); // Set
array element
public void removeMember(String name); // Delete
property
public Object call(String methodName, Object args[]); // Invoke
method
public Object eval(String s); //
Evaluate string
public String toString( ); // Convert
to string
protected void finalize( );
}
Because all JavaScript objects appear in a hierarchy rooted in the current browser
window, JSObject objects must also appear in a hierarchy. To interact with any
JavaScript objects, a Java applet must first obtain a JSObject that represents the browser
window (or frame) in which the applet appears. The JSObject class does not define a
constructor method, so we cannot simply create an appropriate JSObject. Instead, we
must call the static getWindow( ) method. When passed a reference to an applet, this
method returns a JSObject that represents the browser window that contains the applet.
Thus, every applet that interacts with JavaScript includes a line that looks something like

this:
JSObject jsroot = JSObject.getWindow(this); // "this" is the applet
itself
Having obtained a JSObject that refers to the root window of the JavaScript object
.getWindow(this); // self
JSObject document = (JSObject) jsroot.getMember("document"); //
.document
hierarchy, you can use instance methods of the JSObject to read the values of properties
of the JavaScript object that it represents. Most of these properties have values that are
themselves JavaScript objects, so you can continue the process and read their properties
as well. The JSObject
getMember( ) method returns the value of a named property,
while the getSlot( ) method returns the value of a numbered array element of the
specified JavaScript object. You might use these methods as follows:
import netscape.javascript.JSObject; // This must be at the top of the
file
...
JSObject jsroot = JSObject
JSObject applets = (JSObject) document.getMember("applets"); //
.applets
Applet applet0 = (Applet) applets.getSlot(0); //
[0]
You should note two things about this code fragment. First, getMember( ) and getSlot(
) both return a value of type "Object", which generally must be cast to some more
specific value, such as a JSObject. Second, the value read from slot 0 of the applets
array can be cast to an Applet, rather than a JSObject. This is because the elements of the
JavaScript applets[] array are JavaObject objects that represent Java Applet objects.
When Java reads a JavaScript JavaObject, it unwraps that object and returns the Java
object that it contains (in this case, an Applet). The data conversion that occurs through
the JSObject interface is documented later in this chapter.

The JSObject class also supports methods for setting properties and array elements of
JavaScript objects. setMember( ) and setSlot( ) are analogous to the getMember( )
and getSlot( ) methods. These methods set the value of a named property or a
numbered array element to a specified value. Note, however, that the value to be set must
be a Java object. If you want to set a value of a primitive type, use the corresponding Java
wrapper class: use an Integer object instead of an int value, for example. Finally, the
removeMember( ) method allows you to delete the value of a named property from a
JavaScript object.
In addition to reading and writing properties and array elements from JavaScript objects,
the JSObject class allows you to invoke methods of JavaScript objects. The JSObject
call( ) method invokes a named method of the specified JavaScript object and passes a
specified array of Java objects as arguments to that method. As we saw when setting
a
me)
JSObject win = JSObject.getWindow(this);
return (JSObject) win.call("open", args);
orks
s
JavaScript code. You'll find that using eval( ) is often much easier than using the
various other methods of the JSObject class. Since all the code is passed as a string, you
can use string representations of the data types you want -- you do not have to convert
Java primitive types to their corresponding object types. For example, compare the
following two lines of code that set properties of the main browser window:
JavaScript properties, it is not possible to pass primitive Java values as arguments to
JavaScript method; instead you must use the corresponding Java object types. For
example, you might use the call( ) method in Java code like the following to open a
new browser window:
public JSObject newwin(String url, String window_na
{
Object[] args = { url, window_name };

}
The JSObject class has one more important method: eval( ). This Java method w
ust like the JavaScript function of the same name -- it executes a string that containj
jsroot.setMember("i", new Integer(0));
jsroot.eval("self.i = 0");
The second line is obviously easier to understand. As another example, consider the
frame being displayed in the browser
window:
JSObject jsroot = JSObject.getWindow(this);
JSObject parent = (JSObject) jsroot.getMember("parent");
JSObject frames = (JSObject) parent.getMember("frames");
JSObject frame1 = (JSObject) frames.getSlot(1);
JSObject document = (JSObject) frame1.getMember("document");
Object[] args = { "Hello from Java!" };
document.call("write", args);
following use of eval( ) to write a particular
JSObject jsroot = JSObject.getWindow(this);
jsroot.eval("parent.frames[1].document.write('Hello from Java!')");
To do the equivalent without the eval( ) method is a lot harder:
22.2.2 Using JSObjects in Applets
Example 22-1 shows the init( ) method of an applet that uses LiveConnect to interact
with JavaScript.
public void init( )
{
// Get the JSObject representing the applet's browser window.
JSObject win = JSObject.getWindow(this);
// Run JavaScript with eval( ). Careful with those nested quotes!
win.eval("alert('The CPUHog applet is now running on your computer.
" +
"You may find that your system slows down a bit.');");

}
In order to use any applet, you must compile it and then embed it in an HTML file. When
the applet interacts with JavaScript, special instructions are required for both of these
22.2.2.1 Compiling applets that use the JSObject class
Example 22-1. Using JavaScript from an applet method
import netscape.javascript.*
steps.
Any applet that interacts with JavaScript uses the netscape.javascript.JSObject class. To
compile such an applet, therefore, your Java compiler must know where to find a
definition of this class. Because the class is defined and shipped by Netscape and not by
Sun, the javac compiler from Sun does not know about it. This section explains how to
enable your compiler to find this required class. If you are not using the JDK from Sun,
you may have to do something a little different -- see the documentation from the vendor
of your Java compiler or Java development environment.
To tell the JDK compiler where to find classes, you set the CLASSPATH environment
variable. This environment variable specifies a list of directories and JAR files (or ZIP
files) that the compiler should search for class definitions (in addition to its standard
JAR file on your system
h ss. In Netscape 6.1, the file is
plugins/java2/javaplugin.jar, under the Netscape installation directory. In Netscape 4, the
For Internet Explorer, the class definition you need is usually in one of the ZIP files in
is that this directory contains a bunch of ZIP
release to release! The largest of
the files is typically the one you need. You can use an unzip utility to verify that it
Once you have found the JAR or ZIP file you need, you can tell the compiler about it by
TH environment variable. For a Unix system, set a path like this:
gins/java2/javaplugin.jar
And for a Windows system, set a path like this:
set CLASSPATH=.;C:\Windows\Java\Packages\5fpnnz7t.zip
With CLASSPATH set, you should be able to compile your applet with javac as you would

normally.
o.
directory of system classes). The trick is to figure out which
olds the definition of the netscape.javascript.JSObject cla
file is java/classes/java40.jar, under the installation directory. For Netscape 4 on a
Windows system, for example, you would probably find java40.jar at C:\Program
Files\Netscape\Communicator\Program\ Java\Classes\ java40.jar.
c:\Windows\ Java\Packages. The trouble
les, all of whose names are gibberish and change fromfi
contains the file netscape/javascript/JSObject.class.
setting the
CLASSPA
setenv CLASSPATH .:/usr/local/netscape/plu
22.2.2.2 The mayscript attribute
There is an additional requirement for running an applet that interacts with JavaScript. As
a security precaution, an applet is not allowed to use JavaScript unless the web page
author (who may not be the applet author) explicitly gives the applet permission to do s
To give this permission, you must include the new mayscript attribute in the applet's
<applet> tag in the HTML file.
Example 22-1 showed a fragment of an applet that used JavaScript to display an alert
ialog box. Once you have successfully compiled this applet, you might include it in an
HTML file as follows:
If you do not remember to include the mayscript attribute, the applet is not allowed to
use the JSObject class.
22.3 Using Java Classes Directly
As described in the previous two sections, both Netscape and Internet Explorer allow
JavaScript code to interact with Java applets and Java applets to interact with JavaScript.
Netscape's LiveConnect technology also allows JavaScript programs to instantiate their
own Java objects and use them, even in the absence of any applets. Internet Explorer does
not have any analogous capability.

In Netscape, the object provides access to all the Java packages that Netscape
.java.lang refers to the java.lang package, and
the expression Packages.java.lang.System refers to the java.lang.System class. For
ight
LiveConnect allows us
lasses (just as we
d
<applet code="CPUHog.class" width="300" height="300"
mayscript></applet>
Packages
knows about. The expression Packages
convenience, java is a shortcut for Packages.java. In Netscape, JavaScript code m
invoke a static method of this java.lang.System class as follows:
// Invoke the static Java method System.getProperty( )
var javaVersion = java.lang.System.getProperty("java.version");
This use of LiveConnect is not limited to system classes, because
to use the JavaScript new operator to create new instances of Java c
ould in Java).w Example 22-2 shows JavaScript code that uses standard Java classes (the
JavaScript code looks almost identical to Java code, in fact) to pop up a window and
is shown in Figure 22-1display some text. The result .
Figure 22-1. A Java window created from JavaScript
Example 22-2. Scripting the built-in Java classes
var f = new java.awt.Frame("Hello World");
var ta = new java.awt.TextArea("hello, world", 5, 20);

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×