Интерпретаторы JavaScript часто поддерживают возможность обращения к по_ лям и вызова методов Java_объектов. Если сценарий обладает средствами досту_ па к объектам через аргументы методов или объект Bindings, он может взаимо_ действовать с Java_объектами практически так же, как с JavaScript_объектами. И даже если сценарию не передается никаких ссылок на Java_объекты, он может создавать собственные Java_объекты. Netscape стала первой компанией, реализо_ вавшей возможность взаимодействия JavaScript_сценариев с Java_приложения_ ми, когда включила в свой интерпретатор SpiderMonkey средства взаимодейст_ вия с Java_апплетами в веб_броузерах. В Netscape эта технология получила на_ звание LiveConnect. Интерпретатор Rhino, а также реализация JScript, создан_ ная компанией Microsoft, были адаптированы в соответствии с синтаксисом LiveConnect, поэтому название LiveConnect используется на протяжении этой главы для обозначения любой реализации, объединяющей JavaScript и Java.
Начнем этот раздел с обзора некоторых характеристик LiveConnect. В последую_ щих подразделах приводится более подробное описание технологии LiveConnect.
Обратите внимание: Rhino и SpiderMonkey реализуют несколько отличающиеся версии LiveConnect. Функциональные возможности, описываемые здесь, отно_ сятся к интерпретатору Rhino и могут использоваться в сценариях, встроенных в Java 6. Интерпретатор SpiderMonkey, реализующий лишь часть этих возмож_ ностей, рассматривается в главе 23.
Когда Java_объект передается JavaScript_сценарию через объект Bindings или в качестве аргумента функции, JavaScript_код может работать с ним практиче_ ски так же, как если бы это был обычный JavaScript_объект. Все общедоступные поля и методы Java_объекта становятся доступны как свойства объекта_обертки языка JavaScript. Например, допустим, что в сценарий передается Java_объект,
238 Глава 12. Разработка сценариев для Java*приложений
выполняющий рисование диаграмм. Теперь предположим, что в этом объекте объявлено поле с именем lineColor типа String, и что JavaScript_сценарий сохра_ няет ссылку на этот объект в переменной с именем chart. Тогда JavaScript_код может обращаться к этому полю следующим образом:
var chartcolor = chart.lineColor; // Чтение поля Java_объекта. chart.lineColor = "#ff00ff"; // Запись в поле Java_объекта.
Более того, JavaScript_сценарий может даже работать с полями_массивами. До_ пустим, что объект рисования диаграмм определяет следующие два поля (на языке Java):
public int numPoints; public double[] points;
Тогда JavaScript_программа может обращаться к этим полям следующим образом:
for(var i = 0; i < chart.numPoints; i++) chart.points[i] = i*i;
Помимо работы с полями Java_объектов, JavaScript_сценарии могут вызывать методы этих объектов. Например, предположим, что объект рисования диа_ грамм имеет метод с именем redraw(). Данный метод не имеет аргументов и про_ сто сообщает объекту, что содержимое массива points[] изменилось и следует пе_ рерисовать диаграмму. JavaScript_сценарий может вызвать этот метод, как если бы это был метод JavaScript_объекта:
chart.redraw();
Кроме того, JavaScript_сценарий может передавать методам аргументы и полу_ чать возвращаемые значения. Преобразование типов значений аргументов и воз_ вращаемых значений производится по мере необходимости. Предположим, что объект рисования диаграмм объявляет следующие методы:
public void setDomain(double xmin, double xmax); public void setChartTitle(String title);
public String getXAxisLabel();
Тогда JavaScript_сценарий может вызывать эти методы следующим образом:
chart.setDomain(0, 20); chart.setChartTitle("y = x*x"); var label = chart.getXAxisLabel();
Наконец следует отметить, что возвращаемыми значениями Java_методов могут быть Java_объекты, и JavaScript_сценарий может обращаться к общедоступным полям и вызывать общедоступные методы этих объектов. Кроме того, из Java_ Script_кода можно даже передавать Java_объекты в виде аргументов Java_методов. Допустим, что объект рисования диаграмм содержит метод с именем getXAxis(), который возвращает другой Java_объект – экземпляр класса Axis. Допустим так_ же, что этот объект имеет еще один метод с именем setYAxis(), который прини_ мает в качестве аргумента экземпляр класса Axis. И наконец, допустим, что класс Axis объявляет метод с именем setTitle(). Тогда обращаться к этим мето_ дам из JavaScript можно следующим образом:
var xaxis = chart.getXAxis(); // Получить объект Axis var newyaxis = xaxis.clone(); // Создать его копию
12.2. Взаимодействие с Java*кодом
newyaxis.setTitle("Y");
// Вызвать его метод...
chart.setYAxis(newyaxis);
// ...и передать его другому методу
Технология LiveConnect позволяет JavaScript_коду создавать собственные Java_ объекты, т. е. JavaScript_сценарий может взаимодействовать с Java_объектами, даже не получая их извне.
Глобальный символ Packages предоставляет возможность доступа к любым Java_ объектам, которые известны интерпретатору JavaScript. Выражение Package.ja_ va.lang является ссылкой на пакет java.lang, а выражение Package.java.lang.Sys_ tem – на класс java.lang.System. Для удобства было введено еще одно глобальное имя java, которое является сокращением от Package.java. Вызвать статический метод класса java.lang.System из JavaScript_сценария можно следующим образом:
var javaVersion = java.lang.System.getProperty("java.version");
Этим возможности LiveConnect не ограничиваются, т. к. в JavaScript_сценариях допускается применять оператор new для создания новых экземпляров Java_ классов. Для примера рассмотрим фрагмент JavaScript_сценария, в котором соз_ дается и отображается элемент графического интерфейса из Java Swing:
// Определить сокращение для обозначения иерархии пакета javax.* var javax = Packages.javax;
// Создать некоторые Java_объекты.
var frame = new javax.swing.JFrame("Hello World"); var button = new javax.swing.JButton("Hello World");
var font = new java.awt.Font("SansSerif", java.awt.Font.BOLD, 24);
// Вызвать методы новых объектов. frame.add(button); button.setFont(font); frame.setSize(200, 200); frame.setVisible(true);
Чтобы понять, как LiveConnect организует взаимодействие между JavaScript_ и Java_кодом, необходимо понимать, какие типы данных языка JavaScript ис_ пользуются в LiveConnect. Эти типы данных описываются в следующих разделах.