Java & JavaScript: принципы и приемы взаимодействия

© Всероссийский Клуб Веб-мастеров

Рассматриваемые в этой статье возможности подразумевают использование в качестве броузера Netscape Navigator 3.0 или выше. Предполагается, что читатели владеют основами JavaScript и Java.

Известно, что языки JavaScript и Java расширяют возможности представления и обмена информацией на Ваших web-страницах. Но есть ограничения, которые накладываются при использовании этих языков. Вот несколько из них:

Для JavaScript

  1. Поле деятельности жестко ограничивается рамками броузера: все, что существует за его пределами, для JavaScript не существует вовсе. Обмен информацией с внешним миром возможен только при использовании различных HTML-расширений серверов (единого стандарта для которых нет вовсе), CGI и переменной location.search (Решение)
  2. Почти никаких функций для работы с изображениями (за исключением смены картинки в документе при помощи поля src объекта Image) (Решение)
  3. Интерфейс (за исключением форм) статичен и негибок (Решение)

Для Java

  1. Отсутствует возможность динамической генерации документов (Решение)
  2. Отсутствует поддержка E-Mail (если не установлены специальные библиотеки, распространяемые отдельно от JDK) (Решение)
  3. До сих пор не решена проблема отображения символов русского алфавита (если не используется СУБД) (Решение)

Но... Можно заметить, что эти ограничения, накладываемые на один из языков, так или иначе обходятся в другом. Таким образом, обеспечив взаимодействие JavaScript-кода с Java-апплетами, можно еще более повысить гибкость Ваших страниц. В этой статье кратко описывается, как это делается, и даются примеры.

Для того, чтобы разрешить взаимодействие JavaScript и Java, Вам необходимо включить опции Enable Java и Enable JavaScript в меню Options|Network Preferences...|Languages.

Взаимодействие JavaScript и Java-апплетов может осуществляться тремя способами:

Классы пакета netscape:

Доступ из JavaScript к переменным, методам, классам и пакетам Java

Для доступа к классам и пакетам Java в JavaScript есть объект Packages. Используя свойства этого объекта, можно получить доступ к любому классу любого пакета, поддерживаемого навигатором. Напр., для доступа к пакетам java, sun и netscape используются следующие операторы: Packages.java, Packages.sun, Packages.netscape. Строго говоря, при обращении к этим трем пакетам использование Packages необязательно, чего нельзя сказать об остальных пакетах. Так, Packages.java.lang.System.out.println(myString) эквивалентно java.lang.System.out.println(myString).

Пример:

var myDate = new java.util.Date();
var wnd = open();
var doc = wnd.document;
doc.open();
doc.write("<" + "script language="JavaScript1.1">");
doc.write("var myDate = new java.util.Date();");
doc.write("function showStat(param) {");
doc.write("alert(param)}");
doc.write("<" + "/script>");
doc.write(myDate + "<br>");
for (var i in myDate)
  doc.write("<a href='javascript:showStat(myDate." + i + "())'>" +
  	i + "</a><br>");
doc.write("<p><a href='javascript:close()'>Закрыть</a>");
doc.close();

Нажав на кнопку, можно увидеть все переменные и методы вновь созданного объекта (внимание! нажатие на гиперссылку в создаваемом документе успешно выполнит только те методы, которые не принимают параметров (почему, видно из кода выше)):

Внимание! Не используйте любые методы Java, которые могут бросать исключения, т.к. в JavaScript нет обработки исключений, и код, вызывающий такие методы, не пройдет: будет выведено соответствующее сообщение

Управление Java-апплетами и внедренными объектами

Для обращения к Java-апплетам в документе можно использовать один из трех путей:

Напр., если в документе присутствует единственный апплет:

<APPLET CODE=MyAplet.class NAME="myapplet" ...>
...</APPLET>

то следующие три фрагмента кода вернут ссылку на данный апплет:

После получения ссылки на апплет можно получить доступ к любым общедоступным (public) переменным и методам этого апплета.

Пример:

Нажатие на кнопку вызовет установку текста в апплете равным вычисленному выражению в поле ввода формы.

Внедренные объекты

Внедренные объекты (аудио- и видеофайлы WAV, AU, AVI...) вставляются в документ при помощи тэга EMBED (должен быть установлен соответствующий plug-in). Синтаксис:

<EMBED SRC="URL" [WIDTH=widthValue] [HEIGHT=heightValue]>

ЗдесьURL - URL внедряемого объекта. Параметры widthValue и heightValue - размер панели для размещения объекта. Используйте размеры 140 и 60 соответственно для полного показа панели и 2 и 2 для скрытия панели. (Установка размеров в 1x1 или 0x0 в действительности не принесет желаемого результата). Использование параметра NAME не рекомендуется, т.к. при этом часто блокируется работа внедренного объекта (скорее всего, это ошибка в раелизации Netscape Navigator 3.0) autostart=booleanValue - при загрузке объекта он сразу воспроизводится (действительно только для объектов, которые можно воспроизводить)
loop=booleanValue - при true воспроизведение пойдет по циклу (до покидания документа или вызове метода stop

Доступ к внедренным объектам осуществляется при помощи массива document.embeds[index], где в качестве index следует указать индекс объекта (0 соответствует первому внедренному объекту, 1 - второму, ... , document.embeds,length - 1 - последнему).

Чаще всего внедренный объект порождается от класса netscape.plugin.Plugin. В этом случае Вы можете использовать общедоступные переменные и методы данного класса для управления объектом. Кроме этого, каждый тип внедренного объекта может иметь свои собственные переменные и методы. Следующий код позволяет узнать, какие из них доступны в конкретном случае:

var myEmbed = document.embeds[myIndex];
var s = myEmbed + "\n";
for (var i in myEmbed)
  s += i + " = " + myEmbed[i] + "\n";
alert(s);

Общими для всех внедренных объектов являются следующие методы:

Остальные, не указанные здесь, методы используются в основном разработчиками новых внедряемых объектов (plug-ins). Вы не должны их вызывать.
Кроме этого, наиболее часто в объектах присутствуют три метода, которые обеспечивают основные функции управления:
play() - воспроизводит клип (если он таковым является) (при задании в качестве параметра функции true воспроизведение происходит в режиме LOOP)
stop() - останавливает воспроизведение, "перематывая" клип в начало
pause() - приостанавливает воспроизведение. После этого при вызове play() воспроизведение продолжится с того места, где было приостановлено

Доступ из Java-апплетов к методам и свойствам JavaScript

Для того, чтобы разрешить Java-апплетам доступ к методам и свойствам JavaScript, необходимо в тэге APPLET указать атрибут MAYSCRIPT, иначе будет бросаться исключение. Для доступа к JavaScript необходимо импортировать пакет Netscape javascript:

import netscape.javascript.*;

При этом в переменную окружения CLASSPATH необходимо добавить путь к файлу с пакетами, поставляемыми с Netscape Navigator. Напр., если Netscape Navigator установлен в каталог c:\Program Files\Navigator, в CLASSPATH необходимо добавить (для Netscape Navigator Gold) c:\Program Files\Navigator\Program\Java\CLASSES\java_301

Пакет javascript определяет класс JSObject для описания объектов JavaScript и исключение JSException, бросаемое при ошибке во время обращения к объектам JavaScript.

Перед тем, как Вы сможете получить доступ к JavaScript, Вам необходимо получить ссылку на окно (объект window), содержащее апплет:

JSObject win = JSObject.getWindow(this)

Лучше всего включить этот оператор в функцию init() апплета.

Получить доступ к объектам и свойствам JavaScript можно одним из следующих способов:

Вызвать методы объектов JavaScript можно одним из следующих способов:

Преобразование типов от Java к JavaScript:

Преобразование типов от JavaScript к Java:

JSObject - объект JavaScript

Любой объект JavaScript в Java-апплетах представляется потомком класса JSObject (подробнее см. Доступ из Java-апплетов к методам и свойствам JavaScript)

Методы класса JSObject:

JavaScript: обмен информацией с внешним миром

Как известно, Java-апплеты могут обмениваться информацией с тем сервером, откуда он загружен, а если создать соответствующее серверное приложение, то через него и с любым сервером. (Очень хороший пример такого приложения - IDS Server компании IDS Software, взаимодействующий с апплетами с помощью пакетов ids.sql и с серверами или локальными базами данных через систему псевдонимов). Для того, чтобы код JavaScript мог воспользоваться такими возможностями, достаточно в апплете опреденить public-функцию, осуществляющую необходимый способ обмена информацией. После этого JavaScript вызывает данную функцию апплета, когда нужно.

JavaScript: работа с графикой

С помощью Java можно рисовать как на поверхности визуальных компонентов, так и на поверхности изображений (класс Image). Рисование происходит посредством объекта Graphics, являющегося одним из свойств класса Image. Из JavaScript можно напрямую вызывать функции объекта Graphics, предварительно создав в апплете public-переменную:

Graphics myGraph = myImage.getGraphics();

Таким же образом осуществляется рисование на поверхности компонентов апплета.

JavaScript: гибкий интерфейс

Обычно для поддержки взаимодействия с пользователями бывает достаточно использовать формы. Однако часто бывают ситуации, когда возможностей, предоставляемых формами, недостаточно. К тому же в случаях, когда во взаимодействии участвуют несколько HTML-документов (при большом числе вводимых параметров и необходимости динамически изменять последовательность действий), пользователям приходится много времени ждать загрузки тех или иных документов или блоков информации. Все это решается достаточно тривиально с использованием апплетов: хотя апплеты загружаются дольше обычных компонентов документа, это происходит один раз за сессию работы с броузером, а потом работают достаточно быстро. При этом можно создать один документ и все взаимодействие сосредоточить в нем.

Например, если количество вводимых параметров велико, можно установить для апплета (или какой-либо его панели) менеджер компоновки CardLayout и размещать интерфейсные элементы на его страницах (что является аналогом диалоговых окон в виде блокнота с закладками в Windows).

Если же необходимо динамически изменять последовательность действий и/или интерфейсные элементы, то делается это еще проще. В апплетах для изменения набора выводимых элементов предназначены такие функции класса Container, как void remove(Component comp) (для удаления из контейнера элемента comp), void removeAll() (для удаления из контейнера всех элементов) и Component add(Component comp [, int index]) (для добавления нового элемента). И связанная с этим последовательность действий легко изменяется.

Java: динамическая генерация документов

Часто бавает необходимо из Java-апплетов влиять на внешний вид документа в зависимости от некоторых условий (такие условия могут возникнуть в то время, когда документ уже загружен). Например, нужно создать какую-либо таблицу в ответ на введенные пользователем данные. Если контакт апплет загружен с СУБД-сервера, последний может (но не всегда) предоставить некоторые функции для динамической генерации документов. К сожалению, набор таких функций очень ограничен и неудовлетворителен. В других случаях дела обстоят еще сложнее. Таким образом, мы можем в апплете воспользоваться возможностями JavaScript в области создания документов. Для этого есть функция document.write(...). Грамотно используя данную функцию можно построить документ (почти) любой сложности на лету.

Java: поддержка E-Mail

Из JavaScript есть возможности послать сообщение по E-Mail. Есть для этого три способа:

  1. Открывается стандартное окно ввода и отправки сообщения при щелчке на ссылке. Решение для Java-апплетов (если в документе есть ссылка наподобие <A HREF="mailto:rbravant@yahoo.com" NAME=myMail>Send me</A> ):
    JSObject win = JSObject.getWindow(this);
    JSObject doc = (JSObject)win.getMember("document");
    JSObject myMail = (JSObject)doc.getMember("myMail");
    myMail.call("click", null)
    
    Если в тексте ссылки ничего не указать, то ее не будет видно на экране, но она будет функционировать.
  2. Вызывается функция click() кнопки submit формы, в которой в качестве action установлен E-Mail адрес (например, все тот же mailto:rbravant@yahoo.com). Решение для Java-апплетов:
    JSObject win = JSObject.getWindow(this);
    JSObject doc = (JSObject)win.getMember("document");
    JSObject myForm = (JSObject)doc.getMember("formName");
    myForm.call("submit", null);
    
  3. Открывается стандартное окно ввода и отправки сообщения при присваивании location.href значения E-Mail адреса. Решение для Java-апплетов:
    JSObject win = JSObject.getWindow(this);
    JSObject location = (JSObject)win.getMember("location");
    location.setMember("href", "mailto:rbravant@yahoo.com");
      

Java: проблема символов русского алфавита

На самом деле существуют особые механизмы, которые позволяют работать с кириллицей несмотря на то, что в Java такая поддержка отсутствует. Они достаточно нетривиальны, и их рассмотрение выходит за рамки обсуждаемой темы. Есть легкий путь с применением JavaScipt вывода кириллицы в апплете. (Текст, введенный в апплет, может также успешно быть отправлен на сервер, хотя никакой гарантии в этом нет.) Решение таково: в документе в секции SCRIPT определяется ряд переменных с текстом на русском языке (не забудьте защитить символы я и ч обратным слэшем). Получить к ним доступ из апплета не составит труда.