Chapter 22. Using Java with JavaScriptContents:
Scripting Java Applets 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.[73]
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 AppletsAs 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 Copyright © 2003 O'Reilly & Associates. All rights reserved. |
|