Рассматриваемые в этой статье возможности подразумевают использование в качестве броузера Netscape Navigator 3.0 или выше. Предполагается, что читатели владеют основами JavaScript и Java.
Известно, что языки JavaScript и Java расширяют возможности представления и обмена информацией на Ваших web-страницах. Но есть ограничения, которые накладываются при использовании этих языков. Вот несколько из них:
Для JavaScript
Для Java
Но... Можно заметить, что эти ограничения, накладываемые на один из языков, так или иначе обходятся в другом. Таким образом, обеспечив взаимодействие JavaScript-кода с Java-апплетами, можно еще более повысить гибкость Ваших страниц. В этой статье кратко описывается, как это делается, и даются примеры.
Для того, чтобы разрешить взаимодействие JavaScript и Java, Вам необходимо включить опции Enable Java и Enable JavaScript в меню Options|Network Preferences...|Languages.
Взаимодействие JavaScript и Java-апплетов может осуществляться тремя способами:
Классы пакета netscape:
Для доступа к классам и пакетам 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-апплетам в документе можно использовать один из трех путей:
document.appletName
document.applets[index]
document.applets["appletName"]
Напр., если в документе присутствует единственный апплет:
<APPLET CODE=MyAplet.class NAME="myapplet" ...> ...</APPLET>
то следующие три фрагмента кода вернут ссылку на данный апплет:
После получения ссылки на апплет можно получить доступ к любым общедоступным (public) переменным и методам этого апплета.
Пример:
import java.awt.*; import java.applet.Applet; public class myapplet extends Applet { public String myString; TextField myField; public void init() { setLayout(new BorderLayout()); myField = new TextField(); myField.setEditable(false); add("Center", myField); setString("Initial string"); } public void setString(String s) { myField.setText(s); } }
<APPLET CODE=myapplet.class WIDTH=150 HEIGHT=25> </APPLET> <FORM> <INPUT TYPE="text" NAME=mytext SIZE=50> <INPUT TYPE="button" VALUE="Вычислить выражение" onClick="document.applets[0].setString(eval(this.form.mytext.value))"> </FORM>
Нажатие на кнопку вызовет установку текста в апплете равным вычисленному выражению в поле ввода формы.
Внедренные объекты (аудио- и видеофайлы 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);
Общими для всех внедренных объектов являются следующие методы:
getWindow()
- возвращает окно, содержащее документ, в который внедрен данный объект
isActive()
- определяет, является ли данный объект активным в данный момент
Plugin()
- конструктор Остальные, не указанные здесь, методы используются в основном разработчиками новых внедряемых объектов (plug-ins). Вы не должны их вызывать.
Кроме этого, наиболее часто в объектах присутствуют три метода, которые обеспечивают основные функции управления:
play()
- воспроизводит клип (если он таковым является) (при задании в качестве параметра функции true
воспроизведение происходит в режиме LOOP)
stop()
- останавливает воспроизведение, "перематывая" клип в начало
pause()
- приостанавливает воспроизведение. После этого при вызове play()
воспроизведение продолжится с того места, где было приостановлено
Для того, чтобы разрешить 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 можно одним из следующих способов:
eval
объекта window:
JSObject win = JSObject.getWindow(this); JSObject myForm = (JSObject)win.eval("document.myForm");
getMember
объекта JSObject для доступа к свойствам объектов JavaScript:
JSObject win = JSObject.getWindow(this); JSObject doc = (JSObject)win.getMember("document"); JSObject myForm = (JSObject)doc.getMember("myForm");
Вызвать методы объектов JavaScript можно одним из следующих способов:
eval
:
JSObject win = JSObject.getWindow(this); win.eval("alert('My message !')");
call("methodName", argumentsArray)
объекта JSObject:
JSObject win = JSObject.getWindow(this); String argums[] = new String[1]; argums[0] = "My message"; win.call("alert", argums);
Данный способ позволяет вызвать не только методы объекта JavaScript, но и определенные пользователем функции (для чего используйте функцию call
объекта winddow). Если функция/метод не принимает параметры, в качестве второго параметра функции call
указывается пустой массив:
JSObject win = JSObject.getWindow(this); JSObject nav = (JSObject)win.getMember("navigator"); String argums[] = (""); nav.call("javaEnabled", argums);
toString
). Если происходит преобразование в число, вызывается метод Java-объекта floatValue
(который бросит исключение, если такое преобразование невозможно). Аналогично происходит преобразование в boolean (метод booleanValue
)
Любой объект JavaScript в Java-апплетах представляется потомком класса JSObject
(подробнее см. Доступ из Java-апплетов к методам и свойствам JavaScript)
Методы класса JSObject
:
public Object call(String methodName, Object args[])
вызывает метод methodName
объекта JavaScript с аргументами args[]
. Эквивалентен JavaScript-коду:
this.methodName(args[0], args[1], ...)
public Object eval(String s)
вычисляет выражение s
, являющееся любым допустимым выражением JavaScript. Вычисление производится в контексте объекта. Напр., код
JSObject win = JSObject.getWindow(this); JSObject doc = (JSObject)win.eval("document");
в переменную doc
занесет JavaScript-объект document
public Object getMember(String name)
возвращает поле-член JavaScript-объекта. Аналогичен JavaScript-коду this.name
. Напр., код
JSObject win = JSObject.getWindow(this); JSObject doc = (JSObject)win.getMember("document");
в переменную doc
занесет JavaScript-объект document
public Object getSlot(int index)
Возвращает индексированный элемент массива (если объект им является). Аналогичен JavaScript-коду this[index]
. Напр., код
JSObject win = JSObject.getWindow(this); JSObject frames = (JSObject)win.getMember("frames"); JSObject frame1 = (JSObject)frames.getSlot(0);
в переменную frame1
занесет первую (т.е. с индексом 0) рамку окна
public static JSObject getWindow(Applet applet)
Возвращает JavaScript объект-окно, в котором выполняется апплет. Рекомендуется вызывать первым при взаимодействии с JavaScript
public void removeMember(String name)
Удаляет поле-член JavaScript-объекта с именем name
public void setMember(String name, Object value)
Устанавливает значение поля-члена с именем name
в value
. Эквивалентен JavaScript-коду this.name = value
public void setSlot(int index, Object value)
Устанавливает значение индексированного элемента с индексом index
в value
. Аналогичен JavaScript-коду this[index] = value
public String toString()
Преобразует объект JSObject в String
Как известно, Java-апплеты могут обмениваться информацией с тем сервером, откуда он загружен, а если создать соответствующее серверное приложение, то через него и с любым сервером. (Очень хороший пример такого приложения - IDS Server компании IDS Software, взаимодействующий с апплетами с помощью пакетов ids.sql и с серверами или локальными базами данных через систему псевдонимов). Для того, чтобы код JavaScript мог воспользоваться такими возможностями, достаточно в апплете опреденить public-функцию, осуществляющую необходимый способ обмена информацией. После этого JavaScript вызывает данную функцию апплета, когда нужно.
С помощью Java можно рисовать как на поверхности визуальных компонентов, так и на поверхности изображений (класс Image). Рисование происходит посредством объекта Graphics, являющегося одним из свойств класса Image. Из JavaScript можно напрямую вызывать функции объекта Graphics, предварительно создав в апплете public-переменную:
Graphics myGraph = myImage.getGraphics();
Таким же образом осуществляется рисование на поверхности компонентов апплета.
Обычно для поддержки взаимодействия с пользователями бывает достаточно использовать формы. Однако часто бывают ситуации, когда возможностей, предоставляемых формами, недостаточно. К тому же в случаях, когда во взаимодействии участвуют несколько HTML-документов (при большом числе вводимых параметров и необходимости динамически изменять последовательность действий), пользователям приходится много времени ждать загрузки тех или иных документов или блоков информации. Все это решается достаточно тривиально с использованием апплетов: хотя апплеты загружаются дольше обычных компонентов документа, это происходит один раз за сессию работы с броузером, а потом работают достаточно быстро. При этом можно создать один документ и все взаимодействие сосредоточить в нем.
Например, если количество вводимых параметров велико, можно установить для апплета (или какой-либо его панели) менеджер компоновки CardLayout и размещать интерфейсные элементы на его страницах (что является аналогом диалоговых окон в виде блокнота с закладками в Windows).
Если же необходимо динамически изменять последовательность действий и/или интерфейсные элементы, то делается это еще проще. В апплетах для изменения набора выводимых элементов предназначены такие функции класса Container, как void remove(Component comp) (для удаления из контейнера элемента comp), void removeAll() (для удаления из контейнера всех элементов) и Component add(Component comp [, int index]) (для добавления нового элемента). И связанная с этим последовательность действий легко изменяется.
Часто бавает необходимо из Java-апплетов влиять на внешний вид документа в зависимости от некоторых условий (такие условия могут возникнуть в то время, когда документ уже загружен). Например, нужно создать какую-либо таблицу в ответ на введенные пользователем данные. Если контакт апплет загружен с СУБД-сервера, последний может (но не всегда) предоставить некоторые функции для динамической генерации документов. К сожалению, набор таких функций очень ограничен и неудовлетворителен. В других случаях дела обстоят еще сложнее. Таким образом, мы можем в апплете воспользоваться возможностями JavaScript в области создания документов. Для этого есть функция document.write(...). Грамотно используя данную функцию можно построить документ (почти) любой сложности на лету.
Из JavaScript есть возможности послать сообщение по E-Mail. Есть для этого три способа:
<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)Если в тексте ссылки ничего не указать, то ее не будет видно на экране, но она будет функционировать.
JSObject win = JSObject.getWindow(this); JSObject doc = (JSObject)win.getMember("document"); JSObject myForm = (JSObject)doc.getMember("formName"); myForm.call("submit", null);
JSObject win = JSObject.getWindow(this); JSObject location = (JSObject)win.getMember("location"); location.setMember("href", "mailto:rbravant@yahoo.com");
На самом деле существуют особые механизмы, которые позволяют работать с кириллицей несмотря на то, что в Java такая поддержка отсутствует. Они достаточно нетривиальны, и их рассмотрение выходит за рамки обсуждаемой темы. Есть легкий путь с применением JavaScipt вывода кириллицы в апплете. (Текст, введенный в апплет, может также успешно быть отправлен на сервер, хотя никакой гарантии в этом нет.) Решение таково: в документе в секции SCRIPT определяется ряд переменных с текстом на русском языке (не забудьте защитить символы я и ч обратным слэшем). Получить к ним доступ из апплета не составит труда.