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 directly as a property of the Document object. For example,
the applet created by an <applet> tag with a
name attribute of "chart" can be
referred to as document.chart.
The public fields and
methods of every applet are
accessible to JavaScript as if they were the properties and methods
of a JavaScript object. For example, if an applet named
"chart" defines a field named
lineColor whose type is String,
a JavaScript program can query and set this field with code like
this:
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;
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
types. JavaScript is loosely typed and has only a single numeric
type. In the previous example, a Java integer is converted to a
JavaScript number 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:
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 converting JavaScript 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 setDomain(double xmin, double xmax);
public void setChartTitle(String title);
public String getXAxisLabel( );
JavaScript can call these methods with code like this:
document.chart.setDomain(0, 20);
document.chart.setChartTitle("y = x*x");
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. Suppose 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
argument of the same type. Now, suppose further that Axis has a
method named setTitle( ). We might use these
methods with JavaScript code like this:
var xaxis = document.chart.getXAxis( );
// Get an Axis object
var newyaxis = xaxis.clone( );// Make a copy of it
newyaxis.setTitle("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