JavaScript

         

Афиширование и выяснение интерфейсов


В среде JavaBeans существуют способы динамического (то есть не по исходным текстам) выяснения характеристик компонентов. К таким характеристикам относятся:

методы, доступные для вызова другими компонентами и инструментальным окружением; свойства, которые можно опрашивать и/или изменять; события, порождаемые данным компонентом.

Подобное выяснение в терминологии JavaBeans называется интроспекцией*.

Интроспекция используется прежде всего на этапе разработки, в рамках инструментального окружения, позволяя увидеть афишируемые характеристики и с их помощью настроить компонент и связать его с другими элементами приложения.

Принципиальная возможность интроспекции была изначально заложена в Java-технологии. Файлы классов содержат достаточно информации для выяснения всех необходимых характеристик объектов. Воспользоваться этой информацией можно с помощью класса Class, пакета java.lang.reflect и некоторых других средств, которые будут рассмотрены далее. Чтобы оценить полноту сведений, предоставляемых Java-средой, целесообразно рассмотреть фрагменты описаний класса Class (листинг ), а также класса Method из пакета java.lang.reflect (листинг ).

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

Способность компонента среды JavaBeans по существу без дополнительных усилий со стороны разработчика предоставлять информацию о своем интерфейсе называется рефлексией. Рефлексия базируется на дисциплине определения методов. Эта дисциплина состоит в следовании заданным шаблонам при выборе имен методов, а также типов формальных параметров и результатов. Далее, по ходу изложения, мы будем приводить эти шаблоны.

Среда JavaBeans проектировалась таким образом, чтобы в типичных случаях и действия разработчиков, и внутренняя реализация оставались простыми; дополнительные усилия и утяжеление компонентов должны требоваться только тогда, когда этого желает сам программист. В данном случае, если разработчику не хватает выразительной силы рефлексии, он может реализовать интерфейс BeanInfo, явным образом описывающий афишируемые характеристики компонента.

Интерфейс BeanInfo содержит методы, позволяющие получить объекты-описатели характеристик компонента. В число этих методов входят getBeanDescriptor, getMethodDescriptors и т.д. (см. листинги и ). Поскольку реализация методов может быть сколь угодно изощренной, у разработчика появляется возможность ассоциировать с компонентом ресурсы (например, файлы), содержащие описательную информацию. Класс SimpleBeanInfo, входящий в пакет java.beans, является "пустой" реализацией интерфейса BeanInfo, отрицающей наличие у компонента каких-либо афишируемых методов, свойств и событий. Разработчик может создать производный класс и выборочно переопределить методы класса SimpleBeanInfo.

Класс Introspector реализует процесс интроспекции. По заданному компоненту он конструирует объект класса BeanInfo (см. листинг ). Действует Introspector следующим образом. Сначала он пытается найти класс, имя которого получается из имени класса компонента приписыванием текста "BeanInfo". Если такой класс находится, а его методы возвращают непустые дескрипторы, соответствующая информация используется при конструировании результирующего объекта BeanInfo. В противном случае Introspector полагается на механизм рефлексии и анализирует имена и типы параметров public-методов класса компонента и его предшественников.

Характерная особенность Java-технологии состоит в наличии стройной модели безопасности. Применительно к интроспекции действуют два защитных рубежа:

Получение объектов Field, Method и Constructor возможно только путем применения методов класса Class, которые вызывают системный менеджер безопасности. Доступ к полям и методам объектов производится с применением стандартных правил языка Java.

Кроме того, аплеты подвергаются дополнительному контролю.

Детальный анализ модели безопасности Java выходит за рамки данной статьи. Здесь мы отметим лишь, что компонентная объектная среда не привносит каких-либо новых, специфических угроз, поскольку она полностью описывается в терминах языка Java.



Агрегирование интерфейсов


В разных ситуациях компонент объектной среды должен поворачиваться к пользователю разными гранями. Например, в инструментальном окружении необходимо получать информацию об афишируемых характеристиках объекта. В настоящее время такую информацию предоставляет специальный информационной объект, косвенно (по имени класса) ассоциированный с исследуемым и реализующий интерфейс BeanInfo. Однако более естественной была бы не косвенная, а прямая ассоциация, позволяющая единообразно осуществлять доступ к разным "проявлениям" объектов.

Решению сформулированной задачи служит очень важная в концептуальном плане спецификация [4]. Центральное место в ней занимает понятие агрегата - сущности, обладающей "многогранным" поведением, динамически унаследованным у совокупности классов (интерфейсов). В агрегат входят представители соответствующих классов, а также координатор, способный по запросу выдавать нужного представителя.

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

Формально каждый представитель является самостоятельным объектом, принадлежащим своему классу, однако с идейной точки зрения более правильно считать, что метод getInstanceOf () возвращает разные проявления одного (агрегатного) объекта.



Бегущая строка


Бегущая строка в строке статуса

<html>

<head>

<title>Бегущая строка</title>

<script language="javascript">

function statusmessageobject(p,d) { this.msg = message this.out = " " this.pos = position this.delay = delay this.i = 0 this.reset = clearmessage } function clearmessage() { this.pos = position } var position = 100 var delay = 40 var message = "центр информационных" + " технологий" var scroll = new statusmessageobject() function scroller() { for (scroll.i = 0; scroll.i < scroll.pos; scroll.i++) { scroll.out += " " } if (scroll.pos >= 0) scroll.out += scroll.msg else scroll.out = scroll.msg.substring(-scroll.pos,scroll.msg.length) window.status = scroll.out scroll.out = " " scroll.pos-- if (scroll.pos < -(scroll.msg.length)) { scroll.reset() } setTimeout ('scroller()',scroll.delay) } </script>

</head>

<body bgcolor="#000000" onLoad="scroller()">

</body> </html>



Бегущая строка в поле form.

<html>

<head>

<title>Бегущая строка</title>

</head>

<script language="JavaScript">

var line="Центр Информационных Технологий "; var speed=150; var i=0; function m_line() { if(i++<line.length) { document.cit.forum.value=line.substring(0,i); } else{ document.cit.forum.value=" "; i=0; } setTimeout('m_line()',speed); } </script>

<body bgcolor=000000>

<center>

<form name=cit>

<input type=text size=32 name=forum>

</form>

</center>

<script language="JavaScript">

m_line(); </script>

</body>

</html>

Comments:

Copyright ©



Действия, выполняемые источником события


Источник события по своему выбору назначает имя метода, вызываемого в компонентах-подписчиках при распространении события. Чтобы сделать возможной автоматическую интроспекцию компонентов на предмет распространяемых ими событий (то есть для поддержки рефлексии), данный метод описывается в расширении пустого интерфейса java.util.EventListener, играющего роль этикетки. Пример расширения приведен на листинге .

По соглашению, опять-таки направленному на поддержку рефлексии, имя интерфейса-расширения должно оканчиваться цепочкой символов "Listener".

Если источник желает распространять несколько различных событий, допускается описание в одном интерфейсе соответствующего числа методов их обработки.

Метод обработки события должен иметь один аргумент, которым является так называемый событийный объект - преемник класса java.util. EventObject. Посредством этого объекта подписчику передается информация об источнике и другие характеристики события. Определение класса EventObject приведено на листинге . Листинг содержит возможное описание класса KeyPressedEvent (окончание "Event" - еще одно требование рефлексии).

Реализация методов регистрации подписчиков, аннулирования регистрации, а также собственно распространения события может быть выполнена способом, приведенным на листинге . Отметим, что при распространении события вызов методов подписчиков производится синхронным образом, в рамках потока источника события.

Обратим внимание на два аспекта программного текста, приведенного на листинге . Во-первых, в источнике необходимо обеспечить безопасность работы в многопотоковой среде. Методы add/remove выполняются в рамках потоков подписчиков, поэтому они нуждаются в синхронизации. В методе fire также следует учитывать возможность регистрационных действий параллельно с распространением события. Отсюда три вхождения ключевого слова synchronized.

Во-вторых, регистрационные методы должны поддерживать рефлексию и определяться по следующим шаблонам:

public void add ( подписчик); public void remove ( подписчик);

Определение метода fire - внутреннее дело источника события.



Действия, выполняемые подписчиком события


Реализация интерфейса события - основное действие, выполняемое подписчиком. Его содержательная сторона зависит от специфики подписчика. Чисто технические моменты отражены на листинге .

Регистрация подписки производится обращением к соответствующему add-методу источника события.

Общая схема взаимодействия источника и подписчиков события представлена на рис. 2. Если проводить аналогию с обычной подпиской на газеты и журналы, то базовый механизм, описанный в спецификациях JavaBeans, соответствует оформлению подписки в редакции каждого издания (а не в отделении связи). В спецификациях упоминается также о возможности реализации адаптеров - посредников, берущих на себя централизованное оформление подписки и реализацию определенной дисциплины распространения событий. При наличии адаптера схема взаимодействия источников и подписчиков событий может выглядеть так, как показано на рис. 3. Очевидно, подобная схема облегчает жизнь всем взаимодействующим сторонам (не считая адаптера, который необходимо реализовать).

При установлении взаимодействия между источниками и подписчиками событий значительная часть работы может быть выполнена инструментальной средой. Эта среда может сгенерировать код, содержащий обращение к add-методам, обеспечить согласованность названий методов обработки событий, сгенерировав при необходимости вспомогательные классы, и т.п.



Функция escape


Возвращает ASCII значение аргумента, закодированного в ISO Latin-1.



Функция eval


Функция eval выполняет строку-аргумент и подставлает полученное значение вместо себя.



Функция isNaN


Изменена в Navigator 3.0.
На UNIX платформах проверяет аргумент, является ли он "NaN" (не числом).



Функция parseFloat


Анализирует строковый аргумент и возвращает число с плавающей точкой.



Функция parseInt


Анализирует строковый аргумент и возвращает целое число, определенное как основание.



Графические часы


Первый пример - это часы, отображающие время загрузки страницы (т.е. момент вызова скрипта). Используются методы объекта Date (getHours, getMinutes) и графические файлы, отображающие полученное время (имена этих файлов соответствуют цифрам - 0-9).

Во втором примере, отображающем текущую дату, также используются методы объекта Date (getDate, getMnth, getYear) и графические файлы, отображающие полученную дату (имена этих файлов соответствуют цифрам - 0-9).

1.<SCRIPT LANGUAGE="JavaScript">

<!-- // Copyright (c) 1996-1997 Tomer Shiran. All rights reserved. // Permission given to use the script provided that this notice remains as is. // Additional scripts can be found at http: //www.geocities.com/~yehuda /// image files needed: // dg0.gif // dg1.gif // dg2.gif // dg3.gif // dg4.gif // dg5.gif // dg6.gif // dg7.gif // dg8.gif // dg9.gif // dgam.gif // dgpm.gif // dgc.gif // Any set of digit images (0-9), an "am" image, // a "pm" image, and a colon image respectively // will work with this script. // instructions: // Place all image files in a folder / directory. // Add this script, including all comments, to // the desired HTML document. The HTML file must // be located in the same directory as the image // files. document.write(setClock()) function setClock() { // initialize accumulative HTML variable to empty string var text = ""

// set standard convention for digit and punctuation images var openImage = "<IMG SRC=\"" + getPath(location.href) + "dg" var closeImage = ".gif\" HEIGHT=21 WIDTH=16>" // initialize time-related variables with current time settings var now = new Date() var hour = now.getHours() var minute = now.getMinutes() now = null var ampm = "" // validate hour values and set value of ampm if (hour >= 12) { hour -= 12 ampm = "pm" } else ampm = "am" hour = (hour == 0) ? 12 : hour // add zero digit to a one digit minute as spaceholder if (minute < 10) minute = "0" + minute // do not parse this number! // convert minute and hour values to strings minute += "" hour += "" // assign image tags according to the value of hour for (var i = 0; i < hour.length; ++i) { text += openImage + hour.charAt(i) + closeImage } // assign image tag of colon separator to text variable text += openImage + "c.gif\" HEIGHT=21 WIDTH=9>" // assign image tags according to the value of minute for (var i = 0; i < minute.length; ++i) { text += openImage + minute.charAt(i) + closeImage } // assign am / pm image tag to text variable text += openImage + ampm + closeImage // return accumulative HTML string return text}function getPath(url) { lastSlash = url.lastIndexOf("/") return url.substring(0, lastSlash + 1)} // -->

</SCRIPT>

2.<SCRIPT LANGUAGE="JavaScript">

<!-- // Copyright (c) 1996-1997 Tomer Shiran. All rights reserved. // Permission given to use the script provided that this notice remains as is. // Additional scripts can be found at http: //www.geocities.com/~yehuda /// image files needed: // ******************* // dg0.gif // dg1.gif // dg2.gif // dg3.gif // dg4.gif // dg5.gif // dg6.gif // dg7.gif // dg8.gif // dg9.gif // dgp.gif // Any set of digit images (0-9), and a period // image (.) will work with this script. // instructions: // ************* // Place all image files in a folder / directory. // Add this script, including all comments, to // the desired HTML document. The HTML file must // be located in the same directory as the image // files. document.write(setDate()) function setDate() { // initialize accumulative HTML variable to empty string var text = "" // set standard convention for digit and punctuation images var openImage = "<IMG SRC=\"" + getPath(location.href) + "dg" var closeImage = ".gif\" HEIGHT=21 WIDTH=16>" // initialize time-related variables with current date settings var now = new Date() var month = now.getMonth() var date = now.getDate() var year = now.getYear() now = null // convert integer value of month to standard range month++ // 0 - 11 => 1 - 12 // convert minute and hour values to strings month += "" date += "" year += "" // assign image tags associated with month to text variable for (var i = 0; i < month.length; ++i) { text += openImage + month.charAt(i) + closeImage } // assign image tag of period separator to text variable text += openImage + "p.gif\" HEIGHT=21 WIDTH=9>" // assign image tags associated with date to text variable for (var i = 0; i < date.length; ++i) { text += openImage + date.charAt(i) + closeImage } // assign image tag of period separator to text variable text += openImage + "p.gif\" HEIGHT=21 WIDTH=9>" // assign image tags associated with year to text variable for (var i = 0; i < year.length; ++i) { text += openImage + year.charAt(i) + closeImage } // return accumulative HTML string return text}function getPath(url) { lastSlash = url.lastIndexOf("/") return url.substring(0, lastSlash + 1)} // -->

</SCRIPT>

Comments:

Copyright ©



Идущие часики


Идущие часики можно поместить в строке статуса и в поле form. (Реализация объекта Date в Netscape Navigator 2.0 содержит ошибки)
Первый пример - скрипта, создающего часики в строке статуса при загрузке документа:

<html>

<head>

<title>Clock in status bar</title>

<script language="JavaScript">

function clock_status() { window.setTimeout("clock_status()",100); today=new Date(); self.status=today.toString(); } </script>

</head>

<body background="ffffff" onLoad="clock_status()">

</body>

</html>

Второй пример - скрипта, создающего часики (в сокращенном варианте) в поле form

<html>

<head>

<title>Clock</title>

<script language="JavaScript">

function clock_form() { day=new Date() clock_f=day.getHours()+":"+day.getMinutes()+":"+day.getSeconds() document.form.f_clock.value=clock_f id=setTimeout("clock_form()",100) } </script>

</head>

<body bgcolor="ffffff" onLoad="clock_form()">

<center>

<form name=form metod="get">

<input name=f_clock maxlength=8 size=8>

</form>

</center>

</body>

</html>

Третий пример - еще один вариант отображения часиков. Причем обратите внимание, что функция вызывается в теле документа, а не в HTML-теге <body> как в предыдущем примере.

<html>

<head>

<title>Clock full</title>

</head>

<script language="JavaScript">

function fulltime() { var time=new Date(); document.clock.full.value=time.toLocaleString(); setTimeout('fulltime()',500) } </script>

<body bgcolor=ffffff text=ff0000>

<center>

<form name=clock>

<input type=text size=17 name=full>

</form>

<script language="JavaScript">

fulltime(); </script>

</center>

</body>

</html>

В четвертом примере часики с "P.M." и "A.M."

<html>

<head>

<title>Clock</title>

<script language="JavaScript">

var timer=null; var timerrun=false; function stoptime() { if(timerrun) clearTimeout(timer); timerrun=false; } function starttime() { stoptime(); showtime(); } function showtime() { var all=new Date(); var hours=all.getHours(); var minutes=all.getMinutes(); var seconds=all.getSeconds(); var timevalue=" " + ((hours>12) ? hours-12 : hours) timevalue += ((minutes<10) ? ":0" : ":") + minutes timevalue += ((seconds<10) ? ":0" : ":") + seconds timevalue +=(hours>=12) ? "P.M." : "A.M." document.clock.next.value=timevalue; timer=setTimeout('showtime()',1000); timerrun=true; } </script>

<body bgcolor=ffffff text=ff0000 onLoad="starttime()">

<center>

<form name=clock>

<input type=text name=next size=12 value=' '>

</center>

</form>

</body>

</html>

Comments:

Copyright ©



Информация о броузере.


Существуют броузеры, не поддерживающие некоторых возможностей JavaScript. Поэтому, чтобы не возникало ситуаций, когда броузер пользователя не видит чего-либо в вашем документе, можно использовать свойства объекта Navigator: appName и appVersion, которые определяют имя и версию броузера. В зависимости от версии броузера можно осуществлять вызов того или иного документа.
Например, на платформах с 16-разрядной Windows обращение к функции eval() приводит к краху Netscape Navigator 2.0. Поэтому, если мы посмотрим , где используется эта функция, то в нем как раз анализируется имя и версия броузера.

Пример:

<html><head>

<title>Броузер</title>

</head>

<body bgcolor=ffffff>

<center><table border=1>

<tr><td>Имя броузера</td><td>

<script language="JavaScript">

document.write(navigator.appName);</script></td>

<tr><td>Версия броузера</td><td>

<script language="JavaScript">

document.write(navigator.appVersion);</script></td>

<tr><td>Кодовое название броузера</td><td>

<script language="JavaScript">

document.write(navigator.appCodeName);</script></td>

<tr><td>Заголовок пользовательского <br>агента</td><td valign=top>

<script language="JavaScript">

document.write(navigator.userAgent);</script></td>

</table><center>

</body>

</html>

Comments:

Copyright ©



Информация о дате последнего изменения документа.


Для этого в HTML-теге <body> используется свойство lastModified объекта Document. В данном примере такая информация выводится в строку статуса. <body onLoad="status=document.lastModified">

Comments:

Copyright ©



Информация о документе.


Такая информация может быть помещена в строке статуса при загрузке документа. Для этого в HTML-тэг <body> добавлен атрибут onLoad="status='Примеры скриптов. Центр Информационных Технологий'"

Также при попадании указателя мыши в область ссылки вместо имени файла, появляющегося в строке статуса, можно поместить информацию об этом документе.

Обратите внимание, что при загрузке документа в строке статуса одна информация, при попадании указателя мыши в область ссылки - другая, а после выхода указателя мыши из области ссылки - третья. Для этого в HTML-теге <a> добавлены обработчики событий onMouseOver и onMouseOut и свойство status объекта Window:

onMouseOver="status='Примеры скриптов' ;return true" onMouseOut="status='Центр Информационных Технологий' ;return true"

Информацию также можно выводить в диалоговое окно, при этом выполнение программы не прерывается. Для этого используется метод alert() объекта Window и обработчик событий onMouseOver, включенные в HTML-тег <a>. В окне есть кнопка "OK", которая закрывает диалоговое окно.
Например, при попадании указателя мыши в область ссылки открывается диалоговое окно с каким-либо сообщением (лучше, если оно будет не на русском языке).

onMouseOver="alert('Server for Information Technologies')"

Comments:

Copyright ©



Источники информации:


"Справочник Web-мастера", Стивен Спейнаур и Валери Куэрсиа,

Comments:

Copyright ©



История посещений.


Использование объекта History предоставляет возможность возвращаться на URL, который был посещен перед этим (что эквивалентно щелчку на кнопке BACK), и переходить на URL, посещенный перед этим (что эквивалентно щелчку на кнопке FORWARD). Список посещенных URL содержится в меню GO броузера Netscape Navigator.
Делается это, используя методы объекта History: back() и forward(). Для этого в HTML-тег <a> включается следующая строка:

<a href="javascript:history.back()"></a> или <a href="javascript:history.forward()"></a>

Если необходимо вернуться на несколько позиций списка меню GO, то используется метод go(), в скобках указывается целочисленный аргумент (отрицательное значение которого соответствует количеству шагов НАЗАД, положительное -ВПЕРЕД). Например, для возврата на три позиции назад указывается go(-3), вперед - go(3).

Обратите внимание: если нет посещенных перед этим URL, то это не будет работать.

Comments:

Copyright ©



Изменение фона документа.


Изменение фона документа при выборе кнопки с названием цвета. При этом используется свойство bgColor объекта Document.Свойство bgColor в Netscape Navigator 2.0 содержит ошибки.

<html>

<head>

<title>bgcolor</title>

</head>

<body text=000000 bgcolor=ffffff>

<table align=center>

<tr><td><form>

<input type=button value="красный" onClick="document.bgColor='ff0000'">

<input type=button value="желтый" onClick="document.bgColor='ffff00'">

<input type=button value="синий" onClick="document.bgColor='0000ff'">

<input type=button value="голубой" onClick="document.bgColor='87ceeb'">

<input type=button value="коралловый" onClick="document.bgColor='ff7f50'">

</form></td>

</table>

</body>

</html>

Документ с изменяющимся фоном.

<html>

<head>

<title>Изменение фона документа</title>

<script>

function bg_Array() { this.length = bg_Array.arguments.length for (var i = 0; i< this.length; i++) this[i+1] = bg_Array.arguments[i] } var bg_Chars = "0123456789ABCDEF"; function Dec2Hex (Dec) { var a = Dec % 16; var b = (Dec - a)/16; hex = "" + bg_Chars.charAt(b) + bg_Chars.charAt(a); return hex; } function bg_Changer (begin, end, steps) { steps = steps -1 ; redA = begin.charAt(0) + begin.charAt(1); red_valA = parseInt(redA,'16'); redB = end.charAt(0) + end.charAt(1); red_valB = parseInt(redB,'16'); red_int = ((red_valB - red_valA) / steps) * -1; grnA = begin.charAt(2) + begin.charAt(3); grn_valA = parseInt(grnA,'16'); grnB = end.charAt(2) + end.charAt(3); grn_valB = parseInt(grnB,'16'); grn_int = ((grn_valB - grn_valA) / steps) * -1; bluA = begin.charAt(4) + begin.charAt(5); blu_valA = parseInt(bluA,'16'); bluB = end.charAt(4) + end.charAt(5); blu_valB = parseInt(bluB,'16'); blu_int = ((blu_valB - blu_valA) / steps) * -1; step = 2; red = red_valA; grn = grn_valA; blu = blu_valA; document.bgColor = begin; while ( steps >= step ) { red -= red_int; red_round = Math.round(red); red_hex = Dec2Hex(red); grn -= grn_int; grn_round = Math.round(grn); grn_hex = Dec2Hex(grn); blu -= blu_int; blu_round = Math.round(blu); blu_hex = Dec2Hex(blu); document.bgColor = red_hex + grn_hex + blu_hex; step++; } document.bgColor = end; } for (j=0;j<5;j++) { bg_Changer("ffff00","00ff00",50); bg_Changer("00ff00","ff0000",50); bg_Changer("ff0000","0000ff",50); bg_Changer("0000ff","f0ffff",50); bg_Changer("f0ffff","7fff00",50); bg_Changer("7fff00","ff00ff",50); bg_Changer("ff00ff","00ffff",50); bg_Changer("00ffff","eee8aa",50); bg_Changer("eee8aa","ffb6c1",50); bg_Changer("ffb6c1","98fb98",50); bg_Changer("98fb98","afeeee",50); } </script>

</head>

<body>

</body>

</html>

Comments:

Copyright ©



Изменение картинки


В данном примере для этого используется свойство images[ ] объекта Document.

<html>

<head>

</head>

<script language="JavaScript">

<!-- анализируется версия броузера:--> browserName=navigator.appName; browserVer=parseInt(navigator.appVersion); if (browserName=="Netscape" && browserVer >= 3) version="n3"; else version="n2";

if (version=="n3") { graph1green=new Image(20,20); graph1green.src="lgcit.gif"; graph1red=new Image(20,20); graph1red.src="logo.gif"; } function graphON(graphName) { if (version=="n3") { green_red=eval(graphName + "green.src"); document.images[graphName].src=green_red; } } function graphOFF(graphName) { if (version=="n3") { red_green=eval(graphName + "red.src"); document.images[graphName].src=red_green; } } </script>

<body bgcolor=ffffff>

<a href="http://www.cit-forum.com" onMouseOver="graphON('graph1')" onMouseOut="graphOFF('graph1')"><img src="logo.gif" name="graph1" border=0></a>

</body>

</html>

В предыдущем примере изменение происходило при попадании курсора мыши в область картинки и при выходе курсора из нее. В данном примере это организовано в цикле для двух картинок с использованием метода setTimeout.
Работает только в Netscape Navigator 3.0 и выше!

<html>

<head>

<title>Баннер</title>

</head>

<script language="JavaScript">

i=0; img_a=new Array() img_h=new Array() img_a[0]=new Image() img_a[1]=new Image() img_a[0].src="logo.gif" img_a[1].src="lgcit.gif"

function img_b() { document.images[0].src=img_a[i].src document.images[0].src=img_a[i].src i++ if(i>1) i=0; setTimeout("img_b()", 2000) }

</SCRIPT>

</head>

<body bgcolor="#ffffff" onLoad=img_b()>

<img src="logo.gif">

</body></html>

Изменение картинки при загрузке документа в зависимости от текущего времени осуществляется с использованием объекта Date.
Работает во всех броузерах, поддерживающих JavaScript.

<html>

<head>

<title>Баннер</title>

</head>

<script language="JavaScript">

function ban() { j=(new Date()).getSeconds()%2 this[0]="logo.gif" this[2]="lgcit.gif" document.write("<img src=",this[2*j],">")

return (" ");

}

</script>

</head>

<body bgcolor="#ffffff">

<SCRIPT>

document.write(ban()) </SCRIPT>

</body></html>

Comments:

Copyright ©



Компоненты и контейнеры


Представляется удивительным, что спецификация [3], регламентирующая фундаментальное отношение компоненты/контейнер, не вошла в число первоочередных и дорабатывается только сейчас, в рамках новой версии JavaBeans с рабочим названием Glasgow.

Механизм контейнеров необходим для достижения по крайней мере двух целей:

организации иерархической логической структуры компонентов в рамках объектной среды; организации единого контекста для совокупности компонентов, предоставляющего им набор сервисов для взаимодействия между собой и с окружением.

Первый пункт означает, в частности, инкапсуляцию совокупности компонентов, так что с точки зрения окружения она выглядит как единое целое с набором методов, предоставляемых контейнером. Кроме того, применительно к иерархической структуре возможен систематический обход и обработка ее элементов.

Второй пункт имеет противоположное назначение - инкапсуляцию окружения. Контейнер выступает в роли оболочки, скрывающей от компонентов особенности внешней среды и предоставляющей им свой контекст.

Чтобы избежать употребления перегруженного в Java-среде термина "контейнер", авторы спецификации употребляют сочетание "BeanContext". Мы не будем этого делать, поскольку, помимо предоставления общего контекста, у контейнера есть и другие функции; надеемся, что к путанице это не приведет.

Реализация механизма контейнеров использует служебный интерфейс java.util.Collection, который предполагается включить в одну из ближайших версий Java-среды. Фрагмент описания этого интерфейса, содержащий типичные методы для работы с наборами, приведен на листинге .

Интерфейс java.beans.BeanContextChild содержит описания методов, позволяющих ассоциировать с компонентом объемлющий контейнер и опрашивать эту ассоциацию (см. листинг ). Таким образом, связи, ведущие вниз (от контейнера к компоненту), обслуживает интерфейс Collection, а связи, ведущие вверх, - интерфейс BeanContextChild.

С отношением компоненты/контейнер ассоциировано событие beanContextChanged. Соответствующий интерфейс (BeanContextListener) описан на листинге .

Вообще говоря, распространение этого события может происходить в несколько приемов: контейнер, получив извещение от компонента, передает его своим подписчикам, в число которых, вероятно, входит объемлющий контейнер, и т.д. Чтобы распознать подобные "вторичные" события и определить первоисточник, предусмотрены соответствующие методы событийного объекта BeanContextEvent (см. листинг ).

Изменения совокупности компонентов, входящих в контейнер, обслуживает событийный объект BeanContextMembershipEvent. Он содержит информацию о разности ("дельте") между старым и новым составом контейнера, то есть о том, какие компоненты были добавлены или, напротив, удалены (листинг ).

Интегрирующим элементом рассматриваемой спецификации является интерфейс java.beans.BeanContext, описывающий связи, идущие как вверх, так и вниз (за счет расширения интерфейсов BeanContextChild и Collection соответственно). Интерфейс BeanContext позволяет также опросить предоставляемые контейнером сервисы и ресурсы. Содержит он и методы для регистрации подписчиков событий (см. листинг ).

Разумеется, кроме синтаксиса специфицируется семантика методов интерфейса BeanContext.

При добавлении компонента методом add (), унаследованным у интерфейса Collection, контейнер "привязывает" этот компонент к себе, вызывая в нем метод setBeanContext с аргументом this (полноценные компоненты должны реализовывать интерфейс BeanContextChild). В свою очередь, компонент может протестовать против включения в контейнер, возбуждая исключительную ситуацию PropertyVetoException. Если это случится, контейнер обязан отменить добавление, возбудив исключительную ситуацию IllegalArgumentException. При успешном добавлении компонента контейнер распространяет подписчикам событие beanContextChanged с соответствующим объектом-параметром. Контейнер должен подписаться у нового компонента на события, связанные со свойствами последнего, чтобы отслеживать по крайней мере свойство beanContext и не допустить нарушения целостности иерархической структуры. Кроме того, компонент регистрируется как подписчик событий, возбуждаемых контейнером.

При удалении объекта из контейнера производятся обратные действия. В частности, вызывается метод setBeanContext с аргументом null. Если компонент находится в состоянии, не позволяющем произвести удаление, он возбуждает исключительную ситуацию PropertyVetoException, заставляя тем самым контейнер отказаться от удаления.

Отметим, что контейнерная реализация методов интерфейса Collection должна быть безопасной в многопотоковой среде.

Рассмотренная спецификация заполняет очень важную методологическую брешь в JavaBeans. Хотелось бы надеяться, что переход к новой версии прикладного программного интерфейса Java, включающей интерфейс BeanContext, произойдет в ближайшее время.



Коротко о языке Java


Мы позволим себе коротко напомнить читателям некоторые сведения о языке Java, которые понадобятся нам для дальнейшего изложения. Более полное описание языка и ассоциированной технологии можно найти, например, в статье [6].

Java - объектно-ориентированный язык. В его основе лежит понятие класса. Класс является шаблоном для создания объектов; он может содержать данные и методы. Существуют различные режимы доступа к элементам класса - private, protected, public.

Java - полностью объектно-ориентированный язык, каждому понятию которого (класс, объект, метод и т.п.) соответствует класс, поддерживающий программную обработку соответствующих "понятийных" объектов.

Классы в языке Java объединяются в пакеты. Каждый пакет определяет отдельное пространство имен. Все классы, входящие в один пакет, являются дружественными по отношению друг к другу, то есть имеют взаимный доступ к переменным и методам, если противное не оговорено явно посредством спецификаторов private или protected.

Для обозначения наследования используется ключевое слово extends. Класс Object - это корень дерева наследования. Имеется предопределенная иерархия классов, описанная в пакете java.lang.

В языке Java отсутствует множественное наследование, однако наличие понятия интерфейса позволяет смягчить это ограничение. Интерфейс представляет собой набор описаний методов. Классы могут реализовывать интерфейсы. Этот факт обозначается ключевым словом implements в заголовке класса.

Класс Class используется для получения во время выполнения информации о "классовых" свойствах объектов. Типичные методы этого класса - forName (получение объекта класса Class по текстовому имени), newInstance (порождение нового объекта данного класса), getMethods (получение массива объектов, описывающих public-методы класса, в том числе унаследованные).

Java-классы могут быть абстрактными, то есть не до конца конкретизированными. Это означает, что в классе описаны методы, определения которых отсутствуют. Такие методы (как и сам класс) должны снабжаться описателем abstract и конкретизироваться в производных классах.

Для обработки исключительных ситуаций, возникающих во время выполнения программы, в языке Java используется конструкция try/catch/finally. Для передачи информации об исключительной ситуации используются объекты классов - наследников класса Throwable.

Механизм потоков - обязательная черта современных операционных сред. В языке Java потоки представлены посредством класса Thread, интерфейса Runnable, спецификатора метода synchronized и методов класса Object wait и notify.

Java-программы подразделяются на два вида - самостоятельные приложения и аплеты. Последние выполняются в среде Web-навигатора и могут поступать по сети. Приложения и аплеты существенно различаются по мерам безопасности, принимаемым в процессе их работы (аплеты контролируются значительно жестче).

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



public final class Class extends


public final class Class extends Object implements Serializable { // Информация о классе или интерфейсе
public native Class getSuperclass ();
// Возвращает класс-предшественник данного класса
public native Class [] getInterfaces ();
// Возвращает интерфейсы, реализуемые классом
public Field [] getFields () throws SecurityException; // Возвращает public-поля данного класса, в том числе // унаследованные. Возбуждает исключительную ситуацию, // если доступ к этой информации запрещен политикой // безопасности.
public Constructor [] getConstructors () throws SecurityException; // Возвращает public-конструкторы данного класса. // Возбуждает исключительную ситуацию, если доступ // к этой информации запрещен политикой безопасности.
public Method [] getMethods () throws SecurityException; // Возвращает public-методы данного класса, в том числе // унаследованные. Возбуждает исключительную ситуацию, // если доступ к этой информации запрещен политикой // безопасности.
public Method getMethod (String name, Class parameterTypes []) throws NoSuchMethodException, SecurityException; // Возвращает public-метод с заданными именем и типами // параметров. Возбуждает исключительную ситуацию, // если такого метода нет, или если доступ к этой // информации запрещен политикой безопасности
public Method [] getDeclaredMethods () throws SecurityException; // Возвращает все методы, продекларированные в данном // классе. Возбуждает исключительную ситуацию, если // доступ к этой информации запрещен политикой // безопасности . . . }


public final class Method extends Object implements Member { // Информация о методе класса или интерфейса
public Class getDeclaringClass ();
// Возвращает класс или интерфейс, // содержащий декларацию данного метода
public String getName ();
// Возвращает имя метода в виде цепочки символов
public native int getModifiers ();
// Возвращает модификаторы (public, ...), // использованные при описании метода
public Class [] getParameterTypes ();
// Возвращает типы формальных параметров метода
public Class getReturnType ();
// Возвращает тип результата метода
public Class [] getExceptionTypes ();
// Возвращает исключительные ситуации, // возбуждаемые данным методом
public String toString ();
// Возвращает цепочку символов, описывающую метод
public native Object invoke (Object obj, Object args []) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NullPointerException; // Применяет данный метод к объекту obj // с заданным списком параметров . . . }


public class BeanDescriptor extends FeatureDescriptor { // Описатель компонента объектной среды
public BeanDescriptor (Class beanClass);
// Создает описатель по классу компонента
public Class getBeanClass ();
// Возвращает класс компонента
public Class getCustomizerClass ();
// Возвращает класс-настройщик компонента // (см. раздел "Настройка свойств")
. . . }


public interface BeanInfo { // Интерфейс, который нужно реализовать, // чтобы явным образом афишировать характеристики // компонента объектной среды
public abstract BeanDescriptor getBeanDescriptor ();
// Возвращает описатель компонента
public abstract EventSetDescriptor [] getEventSetDescriptors ();
// Возвращает описатели событий, // возбуждаемых компонентом
public abstract PropertyDescriptor [] getPropertyDescriptors ();
// Возвращает описатели афишируемых // свойств компонента
public abstract MethodDescriptor [] getMethodDescriptors ();
// Возвращает описатели афишируемых // методов компонента
public abstract Image getIcon (int iconKind);
// Возвращает иконку, ассоциированную с компонентом
. . . }


public class Introspector extends Object { // Выяснение характеристик компонента объектной среды
public static BeanInfo getBeanInfo (Class beanClass) throws IntrospectionException; // Выясняет афишируемые характеристики компонента. // При нештатном ходе процесса интроспекции // возбуждает исключительную ситуацию
public static String [] getBeanInfoSearchPath ();
// Возвращает массив пакетов, // в которых будут разыскиваться классы BeanInfo
public static void setBeanInfoSearchPath (String path []);
// Устанавливает массив пакетов, // в которых будут разыскиваться классы BeanInfo
. . . }


interface KeyPressedListener extends java.util.EventListener {
void KeyPressed (KeyPressedEvent kpe);
// Метод, вызываемый в подписчиках // при распространении события
}


implements Serializable {
protected transient Object source; // Поле событийного объекта, хранящее информацию // об источнике. Слово transient означает, что поле // является временным и при сохранении объекта // в долговременную память не записывается
public EventObject (Object source);
public Object getSource ();
public String toString ();
// Возвращает представление событийного объекта // в виде цепочки символов }


public class KeyPressedEvent extends java.util.EventObject {
protected transient int KeyCode;
KeyPressedEvent (java.awt.Component source, int Key) { super (source);
KeyCode = Key; }
public int getKeyPressed () { return KeyCode; } }


public abstract class KeyPressedEventSource {
private Vector listeners = new Vector ();
// Массив для хранения набора подписчиков
public synchronized void addKeyPressedListener (KeyPressedListener kpl) { // Зарегистрировать подписчика
listeners.addElement (kpl);
}
public synchronized void removeKeyPressedListener(KeyPressedListener kpl) { // Аннулировать регистрацию
listeners.removeElement (kpl);
}
protected fireKeyPressed (int Key) { // Распространение события (оповещение подписчиков)
Vector l; KeyPressedEvent kpe = new KeyPressedEvent (this, Key);

// Создадим локальную копию набора подписчиков // на момент возникновения события. // В процессе распространения события набор подписчиков // (но не локальная копия!) может изменяться synchronized (this) {l = (Vector) listeners.clone ();
}
// Оповестим подписчиков о наступлении события
for (int i = 0; i < l.size();
i++) { ((KeyPressedListener) l.elementAt(i)).KeyPressed (kpe);
} } }


public class MyListener implements KeyPressedListener {
public void KeyPressed (KeyPressedEvent kpe) { . . . }
}


public Color getPalette (int i);
public void setPalette (int i, Color c);
public Color [] getPalette ();
public void setPalette (Color c []);



public class PropertyChangeEvent extends EventObject {
public PropertyChangeEvent (Object source, String propertyName, Object oldValue, Object newValue);
// Конструктор. Создает событийный объект из источника // события, имени изменяемого свойства, // старого и нового значений
public String getPropertyName ();
// Возвращает имя изменяемого свойства
public Object getNewValue ();
// Возвращает новое значение свойства
public Object getOldValue ();
// Возвращает прежнее значение свойства
. . . }


public interface PropertyChangeListener extends EventListener { public abstract void propertyChange (PropertyChangeEvent pce);
// Метод, вызываемый после изменения // связанного свойства
}


public class PropertyChangeSupport extends Object implements Serializable { // Вспомогательный класс для обслуживания // связанных свойств
public PropertyChangeSupport (Object sourceBean);
// Конструктор
public synchronized void addPropertyChangeListener (PropertyChangeListener pcl);
// Регистрация подписчиков
public synchronized void removePropertyChangeListener (PropertyChangeListener pcl);
// Аннулирование регистрации
public void firePropertyChange (String propertyName, Object oldValue, Object newValue);
// Конструирование событийного объекта и // распространение события. Если новое и старое значения // совпадают, никаких действий не предпринимается
}


public interface PropertyEditor {
public abstract void setValue (Object value);
// Устанавливает редактируемый объект (свойство)
public abstract Object getValue ();
// Возвращает текущее значение свойства
public abstract boolean isPaintable ();
// Истина, если свойство имеет графическое представление // (реализован метод paintValue)
public abstract void paintValue (Graphics gfx, Rectangle box);
// Отрисовывает графическое представление свойства // в заданной области экрана
public abstract String getAsText ();
// Возвращает текстовой представление значения // свойства, доступное для редактирования
public abstract void setAsText (String text) throws IllegalArgumentException; // Устанавливает значение свойства // по текстовому представлению
public abstract boolean supportsCustomEditor ();
// Истина, если поддерживается специализированный // редактор свойства
public abstract Component getCustomEditor ();
// Возвращает специализированный редактор свойства, // которым, вероятно, воспользуется окружение
public abstract void addPropertyChangeListener (PropertyChangeListener pcl);
// Регистрация подписчиков, информируемых // об изменении значения свойства
public abstract void removePropertyChangeListener (PropertyChangeListener pcl);
// Аннулирование регистрации
. . . }


public class PropertyEditorManager extends Object {
public static void registerEditor (Class targetType, Class editorClass);
// Регистрация редактора для типа targetType
public static PropertyEditor findEditor (Class targetType);
// Возвращает редактор для типа targetType
. . . }


public interface Customizer {
public abstract void setObject (Object bean);
// Устанавливает настраиваемый объект
public abstract void addPropertyChangeListener (PropertyChangeListener pcl);
// Настройщик должен возбуждать событие // propertyChange при изменении значения свойства
public abstract void removePropertyChangeListener (PropertyChangeListener pcl);
}


public interface Serializable {
private void writeObject (java.io.ObjectOutputStream out) throws IOException; // Запись объекта в долговременную память
private void readObject (java.io. ObjectInputStream in) throws IOException, ClassNotFoundException; // Чтение объекта из долговременной памяти - метод, // обратный writeObject ()
}


public interface Externalizable extends Serializable {
public abstract void writeExternal (ObjectOutput out) throws IOException; // Сохранение объекта в нестандартном формате
public abstract void readExternal (ObjectInput in) throws IOException, ClassNotFoundException; // Чтение нестандартно сохраненного объекта - // метод, обратный writeExternal ()
}


public class Beans extends Object {
public static Object instantiate (ClassLoader cls, String beanName) throws IOException, ClassNotFoundException; // Создание экземпляра компонента
public static boolean isDesignTime ();
// Истина, если работа идет в инструментальном // окружении
public static boolean isGuiAvailable ();
// Истина, если работа идет в графическом окружении
. . .
}


public interface Collection { public abstract boolean add (Object o) throws ...; // Включает объект в набор. Возвращает "ложь", // если объект там уже был
public abstract void addAll (Collection c) throws ...; // Включает все элементы одного набора в другой
public abstract boolean remove (Object o) throws ...; // Удаляет объект из набора
public abstract void clear () throws ...; // Удаляет все элементы из набора
public abstract boolean contains (Object o);
// Проверяет, входит ли данный объект в набор
public abstract Iterator iterator ();
// Возвращает итератор набора, позволяющий // перебирать элементы
public abstract Object [] toArray ();
// Преобразует набор в массив
. . . }


public interface BeanContextChild extends BeanContextListener {
void setBeanContext (BeanContext bc) throws PropertyVetoException; // Ассоциирует контейнер с компонентом. // Если компонент считает, что новый контейнер ему // не подходит, он возбуждает исключительную ситуацию. // Интерфейс BeanContext описывается ниже, на листинге 26
BeanContext getBeanContext ();
// Опрашивает ассоциацию
. . . }


public interface BeanContextListener extends java.util.EventListener {
void beanContextChanged (BeanContextEvent bce);
// Метод, вызываемый в объектах-подписчиках // при изменениях контейнера
}


public abstract class BeanContextEvent extends java.util.EventObject {
public BeanContext getBeanContext ();
// Возвращает контейнер, распространяющий событие
public synchronized void setPropagatedFrom (BeanContext bc);
// Устанавливает первоисточник события
public synchronized BeanContext getPropagatedFrom ();
// Возвращает первоисточник события
public synchronized boolean isPropagated ();
// Истина, если событие является вторичным
}


public abstract class BeanContextMembershipEvent extends BeanContextEvent {
public boolean isDeltaMember (Object o);
// Истина, если заданный компонент был добавлен // или удален
public Object [] getDeltas ();
// Возвращает добавленные или удаленные компоненты
public boolean isChildrenAddedEvent ();
// Истина, если имело место добавление компонентов
public boolean isChildrenRemovedEvent ();
// Истина, если имело место удаление компонентов
}


public interface BeanContext extends java.beans.BeanContextChild, java.util.Collection {
Object instantiateChild ( String beanName) throws IOException, ClassNotFoundException; // Создает новый экземпляр компонента, заданного // именем, и включает его в себя как в контейнер
Object hasService (Class serviceClass, BeanContextChild requestor);
// Истина, если контейнер предоставляет // запрашиваемый сервис
Object getService (Class serviceClass, BeanContextChild requestor);
// Возвращает сервисный объект запрашиваемого класса
public java.net.URL getResource (String name, BeanContextChild requestor);
// Возвращает универсальный локатор ресурса // с заданным именем
void addBeanContextListener (BeanContextListener bcl);

void removeBeanContextListener (BeanContextListener bcl);
. . . }


public class InfoBus extends Object {
public static synchronized InfoBus open (Component c);
// Получение ссылки на экземпляр шины. // Аргумент используется для определения контекста // (контейнера), для которого подходящая шина, возможно, // уже существует. При необходимости создается // новый экземпляр шины
public static synchronized InfoBus open (String busName);
// Получение ссылки на экземпляр шины. Аргумент задает // желательное имя экземпляра. Обычно используется // не-компонентами (например, инструментальным // окружением)
public synchronized void join (InfoBusMember member) throws PropertyVetoException, InfoBusMembershipException; // Включение заданного компонента в число членов шины. // Компонент, желающий подключиться к шине, должен // реализовать интерфейс InfoBusMember. Экземпляр // шины устанавливается в качестве значения свойства // InfoBus нового члена
public void leave (InfoBusMember member) throws PropertyVetoException; // Выведение компонента из числа членов шины. // Обычно вызывается самим компонентом
public void propertyChange (PropertyChangeEvent event);
// Обработка события, вызванного изменением значения // свойства InfoBus у какого-либо члена шины. Служит // для обеспечения целостности связей между шинами и // их членами
public void addDataProducer (InfoBusDataProducer producer);
public void addDataConsumer (InfoBusDataConsumer consumer);
// Обслуживание подписки на события в экземпляре шины, // запрашиваемой поставщиками и/или потребителями // элементов данных
public void fireItemAvailable (String dataItemName, InfoBusDataProducer producer);
// Распространение среди потребителей события, // состоящего в том, что на шине появился элемент // данных с указанным именем, помещенный заданным // поставщиком
public DataItem findDataItem (String dataItemName, InfoBusDataConsumer consumer);
// Распространение среди поставщиков события, // состоящего в том, что заданный потребитель // нуждается в элементе данных с указанным именем . . .
}


public interface InfoBusMember {
public void setInfoBus (InfoBus infobus) throws PropertyVetoException; // Установка шины, ассоциированной с компонентом. // Обычно вызывается методом InfoBus.join()
public void addInfoBusListener (VetoableChangeListener vcl);
// Обслуживание подписки на возможность запрета // изменения свойства InfoBus
public void addInfoBusListener (PropertyChangeListener pcl);
// Обслуживание подписки на информацию об изменении // свойства InfoBus . . .
}


public class InfoBusMemberImpl extends Object implements InfoBusMember {
public void joinInfoBus (String busName) throws InfoBusMembershipException; // Подключение к шине с заданным именем
public void leaveInfoBus () throws PropertyVetoException, InfoBusMembershipException; // Отключение от шины . . .
}


public class InfoBusEvent extends java.util.EventObject {
InfoBusEvent (String itemName, InfoBusEventListener source);
// Конструктор. Задаются имя ассоциированного // элемента данных и источник события
public String getDataItemName ();
// Возвращает имя ассоциированного элемента данных }


public class InfoBusItemRequestedEvent extends InfoBusEvent {
InfoBusItemRequestedEvent (String itemName, InfoBusDataConsumer consumer);
// Конструктор. Устанавливает пустое значение // свойства DataItem и вызывает конструктор // InfoBusEvent
public void setDataItem (DataItem item);
// Ассоциирует элемент данных с событийным объектом
public DataItem getDataItem ();
// Возвращает ассоциированный элемент данных
public InfoBusDataConsumer getSourceAsConsumer ();
// Возвращает источник события }


public interface Aggregate extends java.rmi.Remote, java.io.Serializable {
Aggregate getInstanceOf (Class requestedInterface);
// Возвращает объект, реализующий методы // заданного интерфейса (класса)
boolean isInstanceOf (Class requestedInterface);
// Истина, если заданный интерфейс (класс) входит // в число поддерживаемых
Enumeration getTypes ();
// Возвращает набор поддерживаемых интерфейсов // (классов) ...
}
Comments:

Copyright ©

Литература


The JavaBeans 1.01 specification. - Sun Microsystems, July, 1997. Java Core Reflection. API and Specification. - Sun Microsystems, February, 1997. L. Cable, G. Hamilton. A Draft Proposal to define an Extensible Runtime Containment and Services Protocol for JavaBeans (Version 0.97). - JavaSoft, August, 1997. L. Cable, G. Hamilton. A Draft Proposal for a Object Aggregation/Delegation Model for JavaBeans (Version 0.8). - JavaSoft, August, 1997. InfoBus Specification. Draft Version 0.04 (First Public Review). - Sun Microsystems, Inc., Lotus Development Corporation, July, 1997. А. Таранов, В. Цишевский. Java как центр архипелага. - Jet Info, 1996, N 9. Ю. Пуха. Объектные технологии построения распределенных информационных систем. - Jet Info, 1997, N 16.

Comments:

Copyright ©



Массив anchors


Вы можете ссылаться на объекты anchor в вашей программе, используя массив anchors. Этот массив содержит запись для каждого тага <a>, содержащего атрибут NAME по порядку встречаемости в документе. Например, если документ содержит три поименованных якоря, то эти якоря представлены как document.anchor[0], document.anchor[1], document.anchor[2].
Использование массива anchors:

document.anchors[index] document.anchors.length


index целое число, представляющее якорь в документе.

Для получения количества якорей в документе используется свойство length: document.anchors.length.
Хотя массив anchors представляет собой поименованные якоря, значение anchors[index] является всегда нулевым. Но если в документе якоря именуются по порядку натуральными числами, вы можете использовать массив anchors и его свойство length для употребления имени якоря перед использованием его в операторах, таких как установка location.hash.
Элементы массива anchors окрыты открыты только для чтения. Например, выражение document.anchors[0]="anchor1" не имеет эффекта.



Массив elements


Массив объектов, содержащий элементы формы (такие как объекты checkbox, radio и text) по порядку встречаемости.



Массив forms



Вы можете ссылаться на формы в вашей программе, используя массив forms (вы можете также использовать имя формы). Этот массив содержит запись для каждого объекта form (тага <FORM>) по порядку встречаемости в документе. Например, если документ содержит три формы, то эти формы представлены так document.forms[0], document.forms[1] и document.forms[2].
Использование массива forms:

document.forms[index] document.forms.length

index целое число, представляющее форму в документе.
Для получения количества форм в документе используется свойство length: document.forms.length.
Вы можете также обращаться к элементам формы, используя массив forms. Например, вы обращаетесь к объекту text с именем quantity во второй форме так:

document.forms[1].quantity.

Элементы массива forms открыты только для чтения. Например, выражение document.forms[0]="music" не имеет эффекта.
Значение каждого элемента в массиве forms является <object nameAttribute>, где nameAttribute является атрибутом NAME формы.



Массив frames


Вы можете ссылаться на объекты frame в вашей программе, используя массив frames. Этот массив содержит запись для каждого фрейма-потомка (тага <FRAME>) в окне, содержащем таг <FRAMESET> по порядку встречаемости. Например, если окно содержит три фрейма-потомка, эти фреймы отображаются как parent.frames[0], parent.frames[1], parent.frames[2].
Использование массива frames:

[frameReference.]frames[index] [frameReference.]frames.length [windowReference.]frames[index] [windowReference.]frames.length

frameReference действительный путь ссылки на фрейм, описанный в объекте .
windowReference переменная windowVar из определения окна (смотрите объект ) или один из синонимов top или parent.
index целое число, представляющее количество фреймов в родительском окне.
Для получения количества фреймов-потомков в окне или фрейме используется свойство length:

[windowReference.]frames.length [frameReference.]frames.length

Элементы в массиве frames открыты только для чтения. Например, выражение [windowReference.]frames[0]="frame1" не имеет эффекта.
Значение каждого элемента в массиве frames является <object nameAttribute>, nameAttribute является атрибутом NAME фрейма.



Массив links


Вы можете ссылаться на объекты link в вашей программе, используя массив links. Этот массив содержит запись для каждого объекта link (тага <A HREF="">) по порядку встречаемости в документе. Например, если документ содержит три объекта link, то эти ссылки представлены так document.links[0], document.links[1] и document.links[2].
Использование массива links:

document.links[index] document.links.length

index целое число, представляющее ссылку в документе.
Для получения количества ссылок в документе используется свойство length: document.links.length.
Элементы в массиве links открыты только для чтения. Например, выражение document.links[0]="link1" не имеет эффекта.



Механизм событий


Согласно спецификациям JavaBeans, у каждого события есть источник и, быть может, один или несколько подписчиков (получателей).

Источник обязан:

выбрать имя метода, вызываемого в компонентах-подписчиках при распространении события. Этот метод должен содержаться в интерфейсе, который является расширением интерфейса EventListener (данное расширение мы будем называть интерфейсом события); реализовать метод регистрации подписчиков события и метод аннулирования регистрации; при распространении события вызвать метод, описанный в интерфейсе события, во всех компонентах-подписчиках.

В свою очередь, подписчик должен предпринять следующие действия:

выполнить реализацию интерфейса события, то есть по сути реализовать метод обработки события (напомним, что имя этого метода выбрал источник); зарегистрироваться в качестве подписчика события.

Рассмотрим перечисленные шаги более подробно.



Метод alert


Отображает диалоговое окно Alert с сообщением и кнопкой OK.



Метод anchor


Создает HTML якорь, который используется как гипертекстовая ссылка.



Метод back


Позволяет вернуться на предыдущий URL в списке посещенных URL'ей.



Метод big


Вызывает строку, отображаемою большим шрифтом, как если установить ей таг <BIG>.



Метод blink


Вызывает мигающую строку, как если установить ей таг <BLINK>.



Метод blur


Изменен в Navigator 3.0.
Убирает фокус с указанного объекта.



Метод bold


Вызывает строку, отображаемую жирным шрифтом, как если установить ей таг <B>.



Метод ceil


Возвращает ближайшее целое числа, округленного в большую сторону или равное числу.



Метод clearTimeout


Окончание задержки, установленной методом setTimeout.



Метод click


Имитирует щелчок мыши на выбранном элементе формы.



Метод close (объект document)


Закрывает поток вывода и завершает вывод данных в рабочую область Navigator'а для отображения.



Метод close (объект window)


Изменен в Navigator 3.0.
Закрывает указанное окно.



Метод confirm


Отображает диалоговое окно с указанным сообщением и кнопками OK и Cancel.



Метод exp


Возвращает enumber, где number является аргументом, а e является экспонентой, основанием натурального логарифма.



Метод fixed


Вызывает строку, отображаемую моноширинным шрифтом, как если установить ей таг <TT>.



Метод floor


Возвращает ближайшее целое числа, округленного в меньшую сторону или равное числу.



Метод focus


Изменен в Navigator 3.0.
Устанавливает фокус на определенный объект.



Метод fontcolor


Вызывает строку, отображаемую установленным цветом, как если поместить ее в таг <FONT COLOR=color>.



Метод fontsize


Вызывает строку, отображаемую установленным размером шрифта, как если поместить ее в таг <FONT SIZE=size>.



Метод forward


Загружает следующий URL в списке посещенных URL'ей.



Метод getTime


Возвращает числовое значение, соответствующее времени для указанной даты.



Метод getTimezoneOffset


Возвращает смещение временной зоны в минутах относительно гринвичского меридиана.



Метод indexOf


Возвращает индекс позиции впервые встреченного искомого значения в вызванном объекте string. Поиск начинается с fromIndex.



Метод italics


Вызывает строку, отображаемую курсивом, как если установить ей таг <I>.



Метод lastIndexOf


Возвращает индекс впервые встреченного искомого значения в вызванном объекте string. Поиск по строке осуществляется в обратном направлении, начиная с fromIndex.



Метод link


Создает гипертекстовую ссылку HTML, по которой можно перейти на другой URL.



Метод log


Возвращает натуральный логарифм числа (по основанию e).



Метод open (объект document)


Открывает поток для получения вывода методами write и writeln.



Метод parse


Возвращает количество миллисекунд в строковом представлении даты, начиная с 1 января 1970 00:00:00, по местному времени.



Метод pow


Возвращает base в степени exponent, т.е. baseexponent.



Метод prompt


Отображает диалоговое окно с сообщением и полем ввода.



Метод random


Изменен в Navigator 3.0.
Возвращает случайное число между нулем и единицей. Этот метод применяется только на UNIX платфомах.



Метод setTimeout


Выполняет выражение по истечении установленного количества миллисекунд.



Метод small


Выводит строку, отображаемую маленьким шрифтом, как если установить ей таг <SMALL>.



Метод strike


Выводит строку, отображаемую как перечеркнутый текст, как если установить ей таг <STRIKE>.



Метод sub


Выводит строку, отображаемую как нижний индекс, как если установить ей таг <SUB>.



Метод sup


Выводит строку, отображаемую как нижний индекс, как если установить ей таг <SUP>.



Метод toGMTString


Переводит дату в строку, используя среднее гринвичское время (GMT).



Метод toLocaleString


Переводит дату в строку, используя местный часовой пояс.



Метод toLowerCase


Возвращает значение вызванной строки, переведенной в нижний регистр.



Метод toUpperCase


Возвращает значение вызванной строки, переведенной в верхний регистр.



Метод UTC


Возвращает количество миллисекунд в объект date, начиная с 1 января 1970 00:00:00, GMT.



Метод write


Пишет одно или более HTML выражений в документ в указанном окне.



Метод writeln


Пишет одно или более HTML выражений в документ в указанном окне, добавляя символ перевода на новую строку в конец выходной информации.



Методы и функции JavaScript


Наталия Бельтикова, Ирина Кузина (РНЦ "Курчатовский институт")

 



Методы и события, ассоциированные со свойствами


Свойства компонентов могут быть скалярными и индексируемыми. Выборка и установка скалярных свойств осуществляется с помощью методов get/set:

public get (); public void set ( p); (такой шаблон заголовков методов необходим для поддержки рефлексии).

Например, если свойством компонента является цвет, соответствующие методы могут описываться как

public Color getColor (); public void setColor (Color c); (класс Color определяется в пакете java.awt).

Особый шаблон предусмотрен для выборки булевых свойств:

public boolean is ();

Вообще говоря, свойства могут быть доступны только на чтение или только на запись; тогда для них определяется лишь один из методов - get или set соответственно.

Индексируемые свойства образуют массивы с целочисленными индексами. С этими массивами можно работать покомпонентно или как с единым целым. Шаблоны соответствующих методов и их примеры приведены на листинге (под здесь понимается тип элемента массива).

Спецификации JavaBeans предусматривают наличие связанных свойств, после изменения которых возбуждается событие propertyChange. Другие компоненты могут подписаться на это событие и, следовательно, получать информацию о производимых изменениях, анализируя объект-параметр PropertyChangeEvent, фрагмент описания которого приведен на листинге .

Метод propertyChange, вызываемый для обработки изменения значения свойства, описан в интерфейсе PropertyChangeListener (листинг ). Источник события, в соответствии с общими правилами (см. раздел ), должен реализовать методы addPropertyChangeListener и removePropertyChangeListener, обеспечивая регистрацию подписчиков.

Вспомогательный класс PropertyChangeSupport, входящий в пакет java.beans, реализует рутинные действия, характерные для обслуживания связанных свойств (см. листинг ). Естественно, разработчики компонентов могут воспользоваться этим классом.

Помимо связанных, спецификации JavaBeans описывают ограниченные свойства, перед изменением значений которых распространяется событие vetoableChange с параметром PropertyChangeEvent. Подписчики этого события могут отклонить планируемое изменение, возбудив исключительную ситуацию PropertyVetoException. Метод set должен отреагировать на подобное вето, вернув прежнее значение, "извинившись" перед уже оповещенными подписчиками (то есть вызвав их методы vetoableChange с обратной парой новое/старое значение) и передав исключительную ситуацию инициатору изменения. Соответственно, заголовок set-метода для ограниченных свойств приобретает следующий вид:

public void set ( p) throws PropertyVetoException;

Синтаксически связанные и ограниченные свойства аналогичны, но реализация последних требует гораздо большей аккуратности и от источников (set-методов), и от подписчиков события vetoableChange. Источнику рекомендуется воспользоваться вспомогательным классом java.beans.VetoableChangeSupport, аккуратно выполняющим все необходимые действия. Подписчикам будет проще, если сделать свойство и ограниченным, и связанным. В таком случае до изменения (при обработке события vetoableChange) подписчики заботятся только о голосовании "за" и "против", а после изменения (при обработке события propertyChange) они выясняют, каким же стало новое значение.



Настройка свойств


Компонент объектной среды особенно полезен тогда, когда его можно настроить. Обычно настройка выполняется во время сборки приложения в инструментальном окружении.

Для несложных компонентов можно представить себе схему настройки, при которой окружение путем интроспекции выявляет афишируемые свойства и порождает электронный бланк, каждая клетка которого соответствует одному свойству. Редактирование содержимого клетки выполняется соответствующим редактором свойства. Редакторы свойств, принадлежащих стандартным типам, входят в Java-окружение; в более сложных случаях должен существовать специализированный редактор, поставляемый с компонентом или с инструментальным окружением.

Класс-редактор свойства должен реализовывать интерфейс PropertyEditor (см. листинг ). Обязательными для реализации являются метод setValue () и один из методов прорисовки и редактирования свойства - в графическом или текстовом представлении. По общим правилам, при изменении значения свойства редактор должен возбуждать событие propertyChange. Отсюда необходимость в реализации методов add/remove.

Для установления ассоциаций между типами данных и их редакторами служит класс PropertyEditorManager. Он поддерживает каталог зарегистрированных редакторов; если же явная регистрация отсутствует, PropertyEditorManager пытается отыскать класс, имя которого образовано приписыванием к имени типа текста "Editor" (см. листинг ).

Для настройки сложных компонентов с большим числом специфических свойств может потребоваться специализированный класс, облегчающий действия пользователей по сравнению со стандартным редактированием бланка. Такой класс-настройщик должен быть прямым или косвенным преемником класса java.awt.Component, одновременно реализуя интерфейс java.beans. Customizer (описание последнего приведено на листинге ).

Чтобы известить окружение о наличии настройщика, компонент должен предоставлять класс BeanInfo и, в частности, реализовывать метод getCustomizerClass класса BeanDescriptor (см. раздел ).

На наш взгляд, механизм свойств специфицирован в среде JavaBeans весьма квалифицированно. В простых ситуациях разработчику компонента не нужно делать ничего; в сложных же случаях он имеет практически полную свободу для самых изощренных реализаций.

Comments:

Copyright ©



Некоторые комментарии


При проектировании механизма событий разработчикам спецификаций JavaBeans пришлось учитывать целую гамму требований:

механизм должен естественным образом интегрироваться в Java-среду; механизм событий должен быть простым и для реализации, и для использования; механизм должен быть расширяемым, поддерживать разные модели распространения событий; механизм должен допускать интеграцию с другими компонентными средами.

Таким образом, задача перед разработчиками стояла трудная, и, на наш взгляд, они не сумели найти достаточно хорошего решения, допустив ряд методологических просчетов.

Если есть система, содержащая n источников событий и m подписчиков, то при использовании базового механизма число связей, которые необходимо поддерживать, имеет порядок n * m. Это много. Напомним, что одним из основных побудительных мотивов развития объектных технологий было понижение внутренней сложности программных систем путем обеспечения относительной независимости компонентов. Использование адаптеров позволяет уменьшить количество связей до величины порядка n + m, однако оно нуждается в стандартизации.

Предлагаемый механизм событий плохо параметризуется, прежде всего потому, что имена методов обработки фиксируются на уровне исходных текстов. Из-за этого трудно писать программы, систематически обрабатывающие различные события. Приходится как минимум наращивать объем программ, что вступает в противоречие с основными положениями Java-технологии.

Пространство событий не структурировано, хотя некоторые действия в некоторых частях среды Java (например, в абстрактном оконном инструментарии, AWT) в этом направлении предприняты. Возможность иерархической организации элементов - одно из необходимых условий успешного создания и сопровождения сложных систем. Здесь это условие нарушено (конечно же, иерархии классов в данном случае недостаточно).

Складывается впечатление, что в предлагаемом виде механизм событий является слишком простым, в нем не хватает ряда понятий. По существу это способ диспетчеризации вызовов методов. Какая-либо "событийность" в такой трактовке попросту отсутствует. Обычно события возникают с частотой, определяемой факторами, внешними по отношению к программной системе, так что необходимо минимизировать по крайней мере время распространения события. При предлагаемом синхронном вызове методов оценить время распространения не представляется возможным. Более того, необходимо позаботиться о противодействии атакам на доступность, производимым путем регистрации подписчика, метод обработки которого не возвращает управления. Часть этих проблем можно решить, реализовав интеллектуальный многопотоковый адаптер, но тогда придется отдельно решать вопросы безопасности, так как ряд защитных мер в Java-технологии основан на прослеживании стека вызовов, и опасность может грозить со стороны зловредного источника событий.

При подготовке спецификаций JavaBeans пришлось пересмотреть механизм событий, первоначально предусматривавшийся абстрактным оконным инструментарием. Весьма возможно, что и версия 1.01 спецификаций JavaBeans не является в этом смысле окончательной. Впрочем, для систем небольшого и среднего масштаба она представляется вполне удовлетворительной.



Объект anchor (массив anchors)


Фрагмент текста, который может быть помещен в гиперссылку.



Объект button


Изменен в Navigator 3.0.
Нажимаемая кнопка в HTML форме.



Объект checkbox


Изменен в Navigator 3.0.
Контрольный переключатель (checkbox) в HTML форме. checkbox является сенсорным переключателем, позволяющим пользователю устанавливать значение on или off.



Объект Date


Изменен в Navigator 3.0.
Позволяет вам работать с датой и временем.



Объект document


Изменен в Navigator 3.0.
Содержит информацию о текущем документе и обеспечен методами отображения HTML-документа.



Объект form (массив forms)


Изменен в Navigator 3.0.
Позволяет пользователям вставлять текст и делать изменения из объектов формы таких как графические опции, селекторные кнопки и списки элементов. Вы можете также использовать форму для отправки данных серверу.



Объект frame (массив frames)


Изменен в Navigator 3.0.
Окно, которое может показывать на одном экране несколько независимо прокручиваемых фреймов, каждый из которых имеет свой собственный URL. Фреймы могут указывать на различные URL'и и быть ссылкой других URL'ей, все внутри одного экрана.



Объект hidden


Изменен в Navigator 3.0.
Текстовый объект формы, который не отображается в HTML форме. Объект hidden используется для передачи пар имя/значение при загрузке формы.



Объект history


Содержит информацию о URL'ях, которые клиент посещал внутри окна. Эта информация сохраняется и доступна через меню Go Navigator'а.



Объект link (массив links)


Изменен в Navigator 3.0.
Кусок текста или картинка, определенные как гипертекстовая ссылка. При выборе пользователем ссылки в тексте, в окно загружается документ, соответствующий этой гипертекстовой ссылке.



Объект location


Изменен в Navigator 3.0.
Содержит информацию о текущем URL.



Объект Math


Изменен в Navigator 3.0.
Встроенный объект, имеющий свойства и методы для математических констант и функций. Например, свойство PI объекта Math имеет значение Пи.



Объект navigator


Изменен в Navigator 3.0.
Содержит информацию о используемой версии Navigator'а.



Объект password


Изменен в Navigator 3.0.
Текстовое поле в HTML форме, значение которого на экране отображается звездочками (*). Когда пользователь вводит текст в это поле, звездочки (*) скрывают введенное значение.



Объект radio


Изменен в Navigator 3.0.
Установка статических кнопок (кнопок radio) в HTML форме. Установка кнопок radio позволяет пользователю выбрать один пункт из списка.



Объект reset


Изменен в Navigator 3.0.
Кнопка сброса (кнопка reset)в HTML форме. Кнопка reset сбрасывает все элементы в форме в их значения, установленные по умолчанию.



Объект submit


Изменен в Navigator 3.0.
Кнопка передачи данных (кнопка submit) в HTML форме. Кнопка submit вызывает передачу формы.



Объект text


Изменен в Navigator 3.0.
Поле ввода текста в HTML форме. Текстовое поле позволяет пользователю вводить слова, фразы или числовой ряд.



Объект textarea


Изменен в Navigator 3.0.
Многострочное поле ввода текста в HTML форме. Поле textarea позволяет пользователю вводить слова, фразы или числа.



Объект window


Изменен в Navigator 3.0.
Объект верхнего уровня для групп объектов document, location и history.



Объекты JavaScript


Наталия Бельтикова, Ирина Кузина (РНЦ "Курчатовский институт")



Обмен данными


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

Соответствующая спецификация [5] готовится специалистами компаний Sun Microsystems и Lotus Development. И хотя совместная работа только началась, мы сочли необходимым осветить выдвинутые предложения ввиду исключительной важности затрагиваемой темы.

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

Информационная шина описывается классом InfoBus. Методы этого класса (реализуемого в рамках виртуальной Java-машины) порождают экземпляры шины, осуществляют подключение компонентов к подходящим экземплярам, отслеживают список шин и подключенных к ним компонентов, распространяет события, обслуживающие обмен данными, и т.п. Фрагмент описания класса InfoBus представлен на листинге .

Процесс информационного взаимодействия компонентов в спецификациях InfoBus можно подразделить на пять фаз:

подключение к шине; прослушивание шины; установление контакта между поставщиком и потребителем, передача элемента данных; выяснение формата элемента данных; интерпретация элемента данных.

Для подключения к шине компонент должен реализовать интерфейс InfoBusMember, получить ссылку на экземпляр шины и войти в число ее членов. Фрагмент интерфейса InfoBusMember приведен на листинге . Обратим внимание, что шина, ассоциируемая с компонентом, трактуется как его свойство, изменение значения которого может отслеживаться на основе механизма событий.

Для облегчения реализации интерфейса InfoBusMember спецификации предлагают класс InfoBusMemberImpl, который, в дополнение к "обязательным", предоставляет еще два удобных метода - joinInfoBus () и leaveInfoBus () (см. листинг ).

Для реализации второй фазы (прослушивание шины) поставщик должен подписаться на информацию о запросах данных, воспользовавшись методом addDataProducer () класса InfoBus. Аналогично, потребитель должен подписаться на информацию о наличии данных, обратившись к методу addDataConsumer (). Компонент может одновременно являться и поставщиком, и потребителем (типичный пример - промежуточное звено конвейера).

Третью фазы информационного взаимодействия компонентов обслуживают преимущественно событийные объекты. В соответствии с моделью, принятой в спецификации InfoBus, поставщик оповещает потребителей о появлении нового элемента данных. Потребители запрашивают у поставщиков данные, когда в них возникает нужда. Обмен элементом данных становится возможным, если поставщик и потребитель используют для него одно и то же имя. Ответственность за надлежащий выбор имен лежит на разработчике приложения.

Класс InfoBusEvent является базовым для событийных объектов поставки/приема. Его описание приведено на листинге .

Поставщик объявляет о наличии новых данных, рассылая всем потребителям шины событийный объект класса InfoBusItemAvailableEvent. Методы этого класса позволяют получить информацию о поставщике и ассоциированный элемент данных.

Потребитель, желающий получить данные, рассылает объект класса InfoBusItemRequestedEvent, описание которого приведено на листинге . Обратим внимание на метод setDataItem, позволяющий поставщику, получившему событийный объект, "привязать" к нему элемент данных, выдав его тем самым инициатору запроса.

Формат элемента данных определяется интерфейсами, которые этот элемент реализует. Базовым интерфейсом элементов данных является DataItem, в число преемников которого входят CollectionAccess, DbAccess и др. Поскольку проблема обмена структурированными данными уже решена в рамках абстрактного оконного инструментария (пакет java.awt.datatransfer), представляется естественным и в спецификациях InfoBus пойти тем же путем, что и было сделано.

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



Обработчик событий onBlur


Изменен в Navigator 3.0.
Событие blur происходит когда поля формы select, text или textarea теряют фокус. Обработчик событий onBlur выполняет программу JavaScript, когда происходит событие blur.
Синтаксис onBlur смотрите в описании соответствующих объектов.



Обработчик событий onChange


Событие change происходит, когда поля формы select, text или textarea теряют фокус и их значения изменяются. Обработчик событий onChange выполняет программу JavaScript, когда происходит событие change.
Обработчик событий onChange используется для подтверждения данных после их изменения пользователем.
Синтаксис onChange смотрите в описании соответствующих объектов.



Обработчик событий onClick


Событие click происходит при щелчке мышью на объекте формы. Обработчик событий onClick выполняет программу JavaScript, когда происходит событие click.
Синтаксис onClick смотрите в описании соответствующих объектов.



Обработчик событий onFocus


Изменен в Navigator 3.0.
Событие focus происходит, когда поле получает фокус ввода с клавиатуры или щелчком мыши. Выбор результатов внутри поля связано с событием select, но не с событием focus. Обработчик событий onFocus выполняет программу JavaScript, когда происходит событие focus.
Синтаксис onFocus смотрите в описании соответствующих объектов.



Обработчик событий onLoad


Событие load происходит, когда Navigator завершает загрузку окна или всех фреймов внутри тага <FRAMESET> . Обработчик событий onLoad выполняет программу JavaScript, когда происходит событие load.
Обработчик событий onLoad используется внутри тагов <BODY> или <FRAMESET>, например, &ltBODY onLoad="...">.
В отношении <FRAMESET> и <FRAME> событие onLoad, размещенное внутри фрейма в таге <BODY>, выполняется перед событием onLoad, размещенном внутри <FRAMESET> в таге <FRAMESET>



Обработчик событий onMouseOver


Событие mouseOver происходит каждый раз, когда курсор мыши попадает на объект. Обработчик событий onMouseOver выполняет программу JavaScript, когда происходит событие mouseOver.
Вы должны возвращать true внутри обработчика событий, если вы хотите использовать свойства status или defaultStatus с обработчиком событий onMouseOver.
Синтаксис onMouseOver смотрите в описании соответствующих объектов.



Обработчик событий onSelect


Событие select происходит, когда пользователь выбирает некоторый текст внутри поля text или textarea. Обработчик событий onSelect выполняет программу JavaScript, когда происходит событие select.
Синтаксис onSelect смотрите в описании соответствующих объектов.



Обработчик событий onSubmit


Изменен в Navigator 3.0.
Событие submit происходит, когда пользователь отправляет форму на Web-сервер. Обработчик событий onSubmit выполняет программу JavaScript, когда происходит событие submit.
Вы можете использовать обработчик событий onSubmit для остановки передачи данных формы; для этого используется выражение return, которое возвращает false в обработчик событий. Любое другое возвращенное значение отправляет форму.
Синтаксис onSubmit смотрите в описании соответствующих объектов.