Изменение фона документа
Афиширование и выяснение интерфейсов
В среде 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 () возвращает разные проявления одного (агрегатного) объекта.
Бегущая строка
Бегущая строка в строке статуса
Бегущая строка в поле form.
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.
2.
Comments:
Copyright ©
Идущие часики
Идущие часики можно поместить в строке статуса и в поле form. (Реализация объекта Date в Netscape Navigator 2.0 содержит ошибки)
Первый пример - скрипта, создающего часики в строке статуса при загрузке документа:
Второй пример - скрипта, создающего часики (в сокращенном варианте) в поле form
Третий пример - еще один вариант отображения часиков. Причем обратите внимание, что функция вызывается в теле документа, а не в HTML-теге как в предыдущем примере.
В четвертом примере часики с "P.M." и "A.M."
Comments:
Copyright ©
Информация о броузере.
Существуют броузеры, не поддерживающие некоторых возможностей JavaScript. Поэтому, чтобы не возникало ситуаций, когда броузер пользователя не видит чего-либо в вашем документе, можно использовать свойства объекта Navigator: appName и appVersion, которые определяют имя и версию броузера. В зависимости от версии броузера можно осуществлять вызов того или иного документа.
Например, на платформах с 16-разрядной Windows обращение к функции eval() приводит к краху Netscape Navigator 2.0. Поэтому, если мы посмотрим , где используется эта функция, то в нем как раз анализируется имя и версия броузера.
| Пример: |
| Имя броузера | |
| Версия броузера | |
| Кодовое название броузера | |
| Заголовок пользовательского агента |
Comments:
Copyright ©
Информация о дате последнего изменения документа.
Для этого в HTML-теге используется свойство lastModified объекта Document. В данном примере такая информация выводится в строку статуса.
Comments:
Copyright ©
Информация о документе.
Такая информация может быть помещена в строке статуса при загрузке документа. Для этого в HTML-тэг добавлен атрибут onLoad="status='Примеры скриптов. Центр Информационных Технологий'"
Также при попадании указателя мыши в область ссылки вместо имени файла, появляющегося в строке статуса, можно поместить информацию об этом документе.
Обратите внимание, что при загрузке документа в строке статуса одна информация, при попадании указателя мыши в область ссылки - другая, а после выхода указателя мыши из области ссылки - третья. Для этого в HTML-теге добавлены обработчики событий onMouseOver и onMouseOut и свойство status объекта Window:
onMouseOver="status='Примеры скриптов' ;return true" onMouseOut="status='Центр Информационных Технологий' ;return true"
Информацию также можно выводить в диалоговое окно, при этом выполнение программы не прерывается. Для этого используется метод alert() объекта Window и обработчик событий onMouseOver, включенные в HTML-тег . В окне есть кнопка "OK", которая закрывает диалоговое окно.
Например, при попадании указателя мыши в область ссылки открывается диалоговое окно с каким-либо сообщением (лучше, если оно будет не на русском языке).
onMouseOver="alert('Server for Information Technologies')"
Comments:
Copyright ©
Источники информации:
Comments:
Copyright ©
История посещений.
Использование объекта History предоставляет возможность возвращаться на URL, который был посещен перед этим (что эквивалентно щелчку на кнопке BACK), и переходить на URL, посещенный перед этим (что эквивалентно щелчку на кнопке FORWARD). Список посещенных URL содержится в меню GO броузера Netscape Navigator.
Делается это, используя методы объекта History: back() и forward(). Для этого в HTML-тег включается следующая строка:
или
Если необходимо вернуться на несколько позиций списка меню GO, то используется метод go(), в скобках указывается целочисленный аргумент (отрицательное значение которого соответствует количеству шагов НАЗАД, положительное -ВПЕРЕД). Например, для возврата на три позиции назад указывается go(-3), вперед - go(3).
Обратите внимание: если нет посещенных перед этим URL, то это не будет работать.
Comments:
Copyright ©
Изменение фона документа.
Изменение фона документа при выборе кнопки с названием цвета. При этом используется свойство bgColor объекта Document.Свойство bgColor в Netscape Navigator 2.0 содержит ошибки.
Документ с изменяющимся фоном.
Comments:
Copyright ©
Изменение картинки
В данном примере для этого используется свойство images[ ] объекта Document.

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

Изменение картинки при загрузке документа в зависимости от текущего времени осуществляется с использованием объекта Date.
Работает во всех броузерах, поддерживающих JavaScript.
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 ©
Литература
Comments:
Copyright ©
Массив anchors
Вы можете ссылаться на объекты anchor в вашей программе, используя массив anchors. Этот массив содержит запись для каждого тага , содержащего атрибут 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 (тага