Java 1.1 Unleashed
- 46 -
Integrating Java and JavaScript
by Rick Darnell
IN THIS CHAPTER
- Setting the Stage
- JavaScript Talking to Java
- Java Talking to JavaScript
- Using JavaScript Methods in Java
By itself, Java is a significant development because of its ability to stretch the
behavior of your Web pages far beyond what was ever imagined for the World Wide Web.
Java can become even more powerful when harnessed with JavaScript.
As you know from other chapters, Java is powerful enough to add animation, sound,
and other features to an applet--but it's very cumbersome to directly interact with
an HTML page. JavaScript isn't big or powerful enough to match Java's programming
power, but it is uniquely suited to work directly with the elements that comprise
an HTML document.
By combining the best features of Java and JavaScript, your applet can interact
with your Web page, offering a new level of interactivity.
Setting the Stage
For Java and JavaScript to interact on your Web pages, they both must be active
and enabled in the user's browser.
To make sure that both features are active in Netscape Navigator when the user
views Java applets, include these simple directions on the opening page of your Web
site for the user to follow:
- 1. Choose Options, Network Preferences from the menu bar. The Preferences
dialog box appears.
2. Select the Languages tab from the Preferences dialog box (see Figure 46.1).
Figure 46.1.
The Languages tab in the Network Preferences dialog box controls whether or
not Java applets and JavaScript commands are processed for HTML documents.
- 3. Both Java and JavaScript are enabled by default. If this has changed,
make sure that both checkboxes are selected.
The steps to include to make sure that both languages are active in Microsoft
Internet Explorer are similar to the steps for Navigator:
- 1. Choose View, Options from the menu bar. The Options dialog box appears.
2. Select the Security tab from the Options dialog box (see Figure 46.2).
Figure 46.2.
Internet Explorer controls which language features are enabled from the Security
tab in the Options dialog box.
- 3. Make sure that the Enable Java Programs checkbox is selected. The scripting
languages available in Internet Explorer--JavaScript and VBScript--are automatically
enabled; there is no way to disable them.
NOTE: Netscape Navigator also includes
a Java Console for displaying applet-generated messages (see Figure 46.3). In addition
to system messages such as errors and exceptions, the Java Console is where any messages
generated by the applet using the java.lang.System package (including System.out.println)
are displayed. To display the Console, select Options, Show Java Console from the
Netscape Navigator menu bar.
The Microsoft Internet Explorer can show the results of system messages also, but
not in real time as Navigator's Java Console can do. All messages are saved in javalog.txt
in C:\Windows\Java. To make sure that this feature is active, select View,
Options from the menu bar, select the Advanced tab in the Options dialog box, and
make sure that the Java Logging checkbox is selected.
Figure 46.3.
The Java Console displays any system messages generated by the applet.
JavaScript Talking to Java
The first and most commonly used communication feature is to modify applet behavior
from JavaScript. This is really quite easy to do with the right information, and
doing so enables your applet to respond to events on the HTML page--including interacting
with forms.
Java syntax is very similar to other JavaScript syntax, so if you're already familiar
with either scripting language, adding Java control is an easy step.
Calling Java Methods
With Navigator 3.0 and later, Netscape provides an object called Packages.
The Packages object allows JavaScript to invoke native Java methods directly.
This object is used in much the same way as the Document or Window
object is in regular JavaScript.
-
NOTE: As you'll recall from earlier discussions,
groups of related classes are combined in a construct called a package. Classes from
a package can be used by outside classes by using the import command.
Just to confuse things, that's not the case with the JavaScript version of Packages.
In JavaScript, the Packages object is the parent object used to invoke native
Java methods, such as Packages.System.out.println("Say Howdy").
CAUTION: Invoking native Java methods
from JavaScript is possible only within Netscape Navigator 3.0 or later. Microsoft
Internet Explorer doesn't include support for the JavaScript-to-Java packages in
its 3.01 release, but may include its own version of this capability in later versions.
The source of the problem is that JavaScript is implemented individually for each
browser; what Netscape includes for JavaScript isn't the same as what Microsoft includes
for JScript. However, Microsoft and Netscape are already working to standardize JavaScript
so that it will work the same across both browser platforms.
Internet Explorer still includes support for all the now-standard features of JavaScript,
including control and manipulation of windows, documents, and forms, although it
still does not include other standard items, such as images.
Here is the syntax to call a Java package from JavaScript directly:
[Packages.]packageName.className.methodName
The object name is optional for the three default packages--java, sun,
and netscape. These three packages can be referenced by their package name
alone, as shown here:
java.className.methodName
sun.className.methodName
netscape.className.methodName
Together with the package name, the object and class names can result in some
unwieldy and error-prone typing. This is why you can also create new variables using
the Package product. The following code assigns a Java package to the variable
System and then uses the System variable to call a method in the
package:
var JavaSystem = Package.java.lang.System;
JavaSystem.out.println("Hello from Java in JavaScript.");
Controlling Java Applets
Controlling an applet with a script is a fairly easy matter, but it does require
some knowledge of the applet you're working with. Any public variable, method, or
property within the applet is accessible through JavaScript.
TIP: If you're changing the values of
variables within an applet, the safest way to do so is to create a new method within
the applet for that specific purpose. The method can accept the value from JavaScript,
perform any error checking, and then pass the new value along to the rest of the
applet. This arrangement helps prevent unexpected behavior or applet crashes.
You have to know which methods, properties, and variables in the applet are public.
Only the public items in an applet are accessible to JavaScript.
-
TIP: Two public methods are common to
all applets, and you can always use them--start() and stop(). These
methods provide a handy way to control when the applet should be active and running.
There are five basic activities common to all applets (as opposed to one basic
activity for applications). An applet has more activities to correspond to the major
events in its life cycle on the user's browser. None of the activities have any definitions.
You must override the methods with a subclass within your applet. Here are the five
activities common to all applets:
- Initialization: This activity occurs after the applet is first loaded.
This activity can include creating objects, setting state variables, and loading
images.
- Starting After being initialized or stopped, an applet is started. The
difference between being initialized and starting is that the former happens only
once; the latter can occur many times.
- Painting The paint() method is how the applet actually gets information
to the screen--from simple lines and text to images and colored backgrounds. Painting
can occur a lot of times in the course of an applet's life.
- Stopping Stopping suspends applet execution and stops the applet from
using system resources. This activity can be an important addition to your code because
an applet continues to run even after a user leaves the page.
- Destroying This activity is the extreme form of stopping. Destroying an
applet begins a clean-up process in which running threads are terminated and objects
and resources are released.
With this information in hand, getting started begins with the <APPLET>
tag. It helps to give a name to your applet to make JavaScript references to it easier
to read. The following snippet of code shows the basic constructor for an HTML applet
tag that sets the stage for JavaScript control of a Java applet. The tag is identical
to the tags you used in previous chapters to add applets, except that a new attribute
is included for a name:
<APPLET CODE="UnderConstruction.class" NAME="AppletConstruction" WIDTH=60 HEIGHT=60>
</APPLET>
Assigning a name to your applet isn't absolutely necessary because JavaScript
creates an array of applets when the page is loaded. However, doing so makes for
a much more readable page.
-
CAUTION: Like the JavaScript Packages
object, the JavaScript applets array is currently available only in Netscape
Navigator 3.0 or later. This doesn't leave Microsoft Internet Explorer completely
out in the cold--JavaScript can still reference an applet in Explorer using the applet's
name.
To use a method of the applet from JavaScript, use the following syntax:
document.appletName.methodOrProperty
-
TIP: Netscape Navigator 3.0 uses an applets
array to reference all the applets on a page. The applets array is used
according to the following syntax:
document.applets[index].methodOrProperty
document.applets[appletName].methodOrProperty
- These two methods also identify the applet you want to control, but the method
using the applet's name without the applets array is the easiest to read
and requires the least amount of typing.
Like other arrays, one of the properties of applets is length,
which returns how many applets are in the document.
This array of applets is not currently available in the Microsoft Internet Explorer
3.0 implementation of JavaScript.
One of the easy methods of controlling applet behavior is starting and stopping its
execution. You start and stop an applet using the start() and stop()
methods common to every applet. Use a form and two buttons to add the functions to
your Web page (see Figure 46.4). The following code snippet is a basic example of
the HTML code needed to add the buttons, with the name of the applet substituted
for appletName:
<FORM>
<INPUT TYPE="button" VALUE="Start" onClick="document.appletName.start()">
<INPUT TYPE="button" VALUE="Stop" onClick="document.appletName.stop()">
</FORM>
Figure 46.4.
One of the simplest ways to control an applet is to use buttons that start
and stop it.
You can also call other methods, depending on their visibility to the world outside
the applet. JavaScript can call any Java method or variable by using a public
declaration.
-
TIP: Any variable or method within the
applet that doesn't include a specific declaration of scope is protected
by default. If you don't see the public declaration, it's not.
The syntax to call applet methods from JavaScript is simple and can be integrated
with browser events, such as the button code snippet just shown. The basic syntax
for calling an applet method from JavaScript is shown here:
document.appletName.methodName(arg1,...,argx)
To call the stop() method from the underConstructionApplet applet
within an HTML page, the syntax is as follows (assuming that the applet is the first
one listed on the page):
document.underConstructionApplet.stop();
Here's how you do it with Navigator (again, assuming that the applet is the first
one listed on the page):
document.applets[0].stop();
Integrating the start() and stop() methods for this applet with
the applet tag and button code snippet used earlier results in the following code:
<APPLET CODE="UnderConstruction" NAME="underConstructionApplet"
WIDTH=60 HEIGHT=60></APPLET>
<FORM>
<INPUT TYPE="button" VALUE="Start"
onClick="document.underConstructionApplet.start()">
<INPUT TYPE="button" VALUE="Stop"
onClick="document.underConstructionApplet.stop()">
</FORM>
Java Talking to JavaScript
The Netscape classes provided with Netscape Navigator 3.0 and later enable Java
to take a direct look at your HTML page through JavaScript objects. This new set
of classes is called LiveConnect. To implement this functionality, you must import
the netscape.javascript.JSObject class when the applet is created.
-
TIP: The netscape.javascript.JSObject
class is included with the other class files in the Netscape folder in the
java_30 file for Netscape 3.0, and in the java_40 file for Netscape
4.0. In Windows, the complete location is \Program Files\Netscape\Navigator\Program\
java\classes. For version 4.0, the Navigator directory name changes
to Communicator.
To enable the Java compiler to find the packages, you have to move the Netscape class
files to your Java/Lib/ directory and give them a zip extension.
Then make sure that the new file is added to your CLASSPATH attribute. The
netscape.javascript.JSObject class extends the standard Java Object
class, so the newly created JSObject objects are treated as other Java objects.
To include the JSObject class as part of your applet, use the import
command as you normally do to include any other class package:
import netscape.javascript.JSObject;
Another important addition is necessary in the applet tag: MAYSCRIPT.
This security feature gives specific permission for the applet to access JavaScript
objects. Here's how to include the tag:
<APPLET CODE="colorPreview.class" WIDTH=50 HEIGHT=50 NAME="Preview" MAYSCRIPT>
Without the MAYSCRIPT parameter, any attempt to access JavaScript from
the applet results in an exception. If you want to exclude an applet from accessing
the page, simply leave out the MAYSCRIPT parameter.
Java and JavaScript Values
The JSObject class gives Java the capability to look at and change objects
defined through JavaScript. This requires certain assumptions, especially when passing
or receiving values from Java. To ensure compatibility, every JavaScript value is
assigned some form from java.lang.Object:
- Objects. Any object sent or received from Java remains in its original
object wrapper.
- Java numbers Because JavaScript doesn't support the variety of numerical
types Java does (byte, char, short, int, long,
float, and double), Java numbers lose their specific type and become
a basic JavaScript number
- JavaScript numbers There's no way to tell what kind of number Java may
be receiving from JavaScript. So all JavaScript numbers are converted to a Java float.
- Booleans and strings These types are passed essentially unchanged. Java
booleans become JavaScript booleans and vice versa. The same is
true for strings.
Looking at the JavaScript Window
To get a handle on JavaScript objects--including form items and frames--you must
first create an object to hold the current Navigator window. The getWindow()
method provides the means to do this.
First, you have to create a new variable of type JSObject. Then, using
the JSObject class, assign the window to the variable:
JSObject jsWin;
jsWin = JSObject.getWindow(this);
-
TIP: This type of work is typically accomplished
within the applet's init() method.
After you have a handle on the window, you can start to break it into its various
components with getMember(). This method returns a specific object from
the next level of precedence. For example, to get a handle on a form on a Web page
with a form called response, you can use the following set of statements:
jsWin = JSObject.getWindow(this);
JSObject jsDoc = (JSObject) jsWin.getMember("document");
JSObject responseForm = (JSObject) jsDoc.getMember("response");
In JavaScript, this form is referred to as window.document.response.
Note that each JavaScript object is assigned to its own variable in Java and is not
a property of a parent object. The form in Java is contained in responseForm,
not in jsWin.jsDoc.responseForm.
NOTE: All parts of an HTML document exist
in JavaScript in set relationships to each other. This arrangement is called instance
hierarchy because it works with specific items on the page, rather than with general
classes of items.
- At the top of the pyramid is the window object. It is the parent of
all other objects. Its children include document, location, and
history, which share a precedence level. The document object's
children include objects specific to the page, such as forms, links, anchors, and
applets.
The Java netscape package recognizes and uses this hierarchy through
its getWindow() and getMethod() methods. The first gets the window
object (the highest object); the latter returns individual members of the next level.
So far, you've retrieved only broad objects, such as windows and forms. Getting
a specific value from JavaScript follows the same principles, although now you need
a Java variable of the proper type to hold the results instead of an instance of
JSObject.
-
TIP: Don't forget about passing numbers
between JavaScript and Java. All JavaScript numbers are converted to a float
type. You can cast it to another Java type if necessary once the value is in the
applet.
Returning to the form example described earlier in this section, suppose that
there is a text field (name), a number (idNum), and a checkbox
(member). You can retrieve each of these values from JavaScript using the
following commands:
jsWin = JSObject.getWindow(this);
JSObject jsDoc = (JSObject) jsWin.getMember("document");
JSObject responseForm = (JSObject) jsDoc.getMember("response");
JSObject nameField = (JSObject) responseForm.getMember("name");
JSOBject idNumField = (JSObject) responseForm.getMember("idNum");
JSOBject memberField = (JSObject) responseForm.getMember("memberField");
String nameValue = (String) nameField.getMember("value");
Float idNumValue = (Float) idNumField.getMember("value");
Boolean memberValue = (Boolean) memberField.getMember("checked");
This chunk of code quickly becomes unwieldy, especially when several values are
needed from JavaScript. If you have to access more than several elements on a page,
it can help to create a new method to handle the process.
The getElement() method defined in the next code snippet accepts the
name of a form and element on an HTML page as arguments and returns the JSObject
that contains it:
protected JSObject getElement(String formName, String elementName) {
JSObject jsDoc = (JSObject) JSObject.getWindow().getMember("document");
JSObject jsForm = (JSObject) jsDoc.getMember(formName);
JSObject jsElement = (JSObject) jsElement.getMember(elementName);
return jsElement;
}
This simple method creates the intervening JSObject objects needed to
get to the form element, making the retrieval as easy as knowing the form and element
name. If the form or form element is not included on the page, the method throws
an exception and halts the applet. And because the instances of JSObject
are contained within the method, system resources are conserved.
To change a JavaScript value from an applet, use the JSObject.setMember()
method. The syntax is setMember(name, value), where name
is the name of the JavaScript object, and value is its new value. The following snippet
uses the getElement() method just defined to get the name element
from the response form, and then uses the JSObject's setMember()
method to set its value to Your Name Here. This is equivalent to the this.name
= newValue statement in JavaScript.
JSObject nameField = getElement("response","name");
nameField.setMember("name","Your Name Here");
The getWindow() and getMember() methods just described are the
basic methods used when interfacing with JavaScript. Together, they make receiving
values from an HTML page with JavaScript a straightforward task--even if the process
is a little cumbersome in the number of statements required.
Getting Values Using Indexes
If your applet is designed to work with a variety of HTML pages that may contain
different names for forms and elements, you can use the JavaScript arrays with the
JSObject slot methods. If the desired form is always the first to appear
on the document and the element is the third, then the form name is forms[0]
and the element is elements[2].
After retrieving the document object using getWindow() and getMember(),
use getSlot(index) to return a value within it. For example, in an HTML
document containing three forms, the second is retrieved into Java using the following
commands:
JSOBject jsWin = JSObject.getWindow(this);
JSObject jsDoc = (JSObject) jsWin.getMember("document");
JSObject jsForms = (JSObject) jsDoc.getMember("forms");
JSObject jsForm1 = (JSObject) jsForms.getSlot(1);
In this syntax, the index is an integer and the value is a String, boolean,
or float.
TIP: One rule that must stand firm is
the placement of the form and the elements within it. When the applet is used with
more than one document, the forms and elements must be in the same relative place
every time to avoid exceptions and unpredictable results.
Using JavaScript Methods in Java
The netscape class package provides two methods to call JavaScript methods
from within an applet: call() and eval(). The syntax differs slightly
for the two methods, but the outcome is the same.
-
TIP: You need a handle for the JavaScript
window before you can use the call() and eval() methods.
There are two ways to invoke these methods. The first uses a specific window instance;
the second uses getWindow() to create a JavaScript window just for the expression:
jsWin.callOrEval(arguments)
JSOBject.getWindow().callOrEval(arguments)
The call() method separates the method from its arguments. This is useful
for passing Java values to the JavaScript method. The syntax is call("method",
args), where method is the name of the JavaScript method you want to
call and args is an array of the arguments you want to pass.
The eval() method, on the other hand, uses a string that appears identical
to the way a method is called within JavaScript. The syntax is eval("expression"),
where expression is a complete method name along with its arguments, such as document.writeln(`Your
name here.'"). The entire statement is wrapped within a string and passed
to JavaScript. Here's what it looks like when you include the string with the eval()
expression:
eval("document.writeln(\'Your name here.\');")
TIP: To pass quotation marks as quotation
marks to JavaScript within a Java string, use the backslash character before each
occurrence.
Summary
Netscape's LiveConnect gives you a whole set of tools to get from JavaScript to
Java and back again. The marriage of these two Web technologies can open up a whole
new world of how to interact with your users. By using simple statements and definitions--already
a part of both languages--you can make a previously static Web page communicate with
an applet embedded in it; in return, the Web page can react to the output of the
applet.
JavaScript-to-Java communication is a simple extension of JavaScript's functionality.
As long as your applets have names, any applet's public method is accessible
to your HTML page. And using the new Netscape package netscape.javascript
makes the process a two-way street: Your Java applet can invoke JavaScript functions
and look at the structure of your Web page as represented by the JavaScript document
object.
This combination is one more set of capabilities in your toolbox that you can
use to meet your users' needs.
|