Модели обработки событий


Содержание

Модели обработки событий

Глава 1 7 Модели обработки событий

Несмотря на существенные изменения механизма обработки событий в AWT, Java1.1 поддерживает обратную совместимость с моделью об

Модель обработки событий Java 1.0

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

Каждый компонент может обрабатывать события, заместив определенные методы, вызываемые используемой по умолчанию реализацией метода handleEvents класса Component. Этот метод вызывается с объекто

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

  • mouseEnter вызывается в том случае, когда мышь входит в компонент.
  • mouseExit вызывается при выходе мыши из области компонента.
  • mouseMove вызывается при перемещении мыши в области компонента.
  • mouseDown вызывается при нажатии кнопки мыши.
  • mouseDrag вызывается при перемещении мыши с нажатой кнопкой.
  • mouseUp вызывается при отпускании кнопки мыши.

Аналогично, keyDown и keyUp вызываются при каждом нажатии и отпускании клавиши. Событие передается методу вместе с кодом нажатой клавиши. Событие можно проверить, чтобы посмотреть, нажаты ли в

Наконец, для работы со специальными событиями, например, с обратными вызовами (callback) из компонентов Button, Scrollbar и Menu, вам придется замещать метод action. Этот метод вызывается с исх

А вот и пример на обработку событий. Мы добавили объект Label к примеру с игрой в “пятнашки”, а также заместили метод action для того, чтобы обрабатывать события, возникающие при нажатии кнопок

public class EventDemo extends Applet <

static final int n = 4;

Label lab = new Label(«?», Label.CENTER);

public void init() <

setLayout(new GridLayout(n, n));

setFont(new Font(«Helvetica», Font.BOLD, 24));

int height = Integer.parseInt(getParameter(«height»));

for (int i = 0; i 0)

add(new Button(«» + k));

lab.setFont(new Font(«Helvetica», Font.ITALIC, 24));

public boolean action(Event e, Object o) <

if (o instanceof String) <

Элементы и связанные с ними события

В таблице 5 для каждого элемента пакета AWT перечислены типы со

В столбцах с третьего по седьмой указано, устанавливаются ли значения переменных -when (время события), х (координат

События, перечисленные для элементов класса Component, применимы ко всем подклассам класса java.awt. Component

Таблица 5. Элементы AWT и события Java 1.0,

Концептуальная модель для систем обработки событий

Рубрика: 1. Информатика и кибернетика

Дата публикации: 04.10.2013

Статья просмотрена: 56 раз

Библиографическое описание:

Серова Е. А. Концептуальная модель для систем обработки событий [Текст] // Технические науки: традиции и инновации: материалы II Междунар. науч. конф. (г. Челябинск, октябрь 2013 г.). — Челябинск: Два комсомольца, 2013. — С. 15-19. — URL https://moluch.ru/conf/tech/archive/87/4293/ (дата обращения: 12.11.2020).

Обзор сценария обработки событий

Разработаем сценарий обработки событий:

— Сценарий составления учебных модулей для системы дистанционного обучения (ДО).

После изложения сценария отобразим на нем различные концепции обработки событий и рассмотрим возникающие при этом преимущества.

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

Сценарий составления учебных модулей для системы ДО

Сценарий описывает выполнение тестовых учебных модулей в системе дистанционного обучения учащимся (группой учащихся). Каждый учащийся имеет доступ в личный кабинет при помощи логина и пароля. В соответствии с выбранным учебным курсом учащийся должен изучать каждый учебный модуль в течение 2 часов. Для каждого учебного материала установлено правило, если более 60 % учащихся не выполняют учебный модуль за отведенное время, учебный модуль отправляется на экспертизу группе технического обслуживания, модератору, преподавателю на доработку/исправление ошибок.

Рис. 1. Обзор сценарий составления учебных модулей для системы ДО

Идеи данного сценария основаны на решениях IBM. Вот некоторые цели, которые преследуют составители и организаторы дистанционных учебных курсов:

— Уменьшить время на освоение учебного материала.

— Отслеживать работу учащихся и приложения.

— Предоставлять оперативную информацию потребителям событий.

— Найти оптимальное сочетание информационно справочного материала, лабораторных работ, контрольных заданий и т. д..

— Снизить оперативные затраты.

— Уменьшить незапланированные затраты на обслуживание.

Чтобы составлять учебные модули, учебное заведение (университет, колледж, школа, центр дополнительного образования) выбирает использование обработки событий в рамках своей системы. В результате учебное заведение способно быстро реагировать и исправлять/дополнять учебные модули. Благодаря обработке событий учебное заведение может влиять на возможности и риски по мере их материализации и принимать решения о дальнейших действиях. Учебное заведение также способна осуществлять изменения и реализовывать их быстро и уверенно, просто меняя логику или приложения обработки событий.

В следующих разделах мы рассмотрим применяемые события и концепции обработки событий для данного сценария.

Отобразим определения и компоненты сети обработки событий на сценарии составления учебных модулей для системы ДО.

Ниже перечислены компоненты сети обработки событий, описывающие не все аспекты, упомянутые в качестве целей информационной системы. Учебное заведение руководствуется определенными правилами. В частности, выполнение одного учебного модуля не должно превышать 2 часов. Любой учащийся, превысивший это время, нуждается в отдыхе, а учебный модуль в доработке, если число учащихся не выполнивших учебный модуль превышает 60 %. Имеется система оповещения учащихся, из которой формируются события начала и конца выполнения учебного модуля. На основе этих событий можно выполнить процесс передачи учебного модуля модератору, технической группе и т. д. Кроме того, имеются определенные требования к пополнению событий информацией, обнаружению шаблона «превышение времени на выполнение задания» и маршрутизации, которые описаны в виде агентов обработки событий.

Производители событий

Производитель событий

Описание

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

Система оповещения учащихся

Часть электронного учебника.

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

Потребители событий

Потребитель событий

Описание

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

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

Знакомит с учебным планом, с электронным учебником; направляет, консультирует, выдает задания

Решает вопросы зачисления/отчисления обучающихся, проводит регистрацию пользователей — обучающихся в системе ДО (пароли доступа, снабжение необходимыми пособиями, рекомендациями)

Исправляет ошибки в программных средствах, сетевых ресурсах. Обеспечивает работу необходимых программных средств, доступ к комплексу информационно-учебных серверов.

Типы событий

Идентификатор события

Тип события

Атрибуты

Комментарии

Уведомление о входе учащегося в учебный модуль

Отметка времени; идентификатор учащегося

Уведомление о входе учащегося в учебный модуль(расширенное)

Отметка времени; идентификатор учащегося; идентификатор устройства (номер компьютера); фамилия учащегося

Уведомление о выходе учащегося из учебного модуля

Отметка времени; идентификатор учащегося

Может быть основано на структуре E1.

Время выполнения учебного модуля превышено

Отметка времени; идентификатор учащегося; идентификатор устройства; фамилия учащегося

Уведомление о передаче учебного модуля на доработку

Отметка времени; идентификатор учащегося; идентификатор устройства; идентификатор модератора

На рисунке 2 схематически показаны компоненты этой EPN.

Рис. 2. Графическое представление EPN

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

Определив в предыдущем разделе различных участников (производителей и потребителей сообщений), события и агенты обработки событий, можно отобразить сценарий на концептуальную архитектуру обработки событий (см. рисунок 3). Взаимосвязь производителей и потребителей событий довольно очевидна. Все агенты, за исключением агента маршрутизации A4, отображаются на компонент обработки событий в шине событий. В отображения на генератор событий и на часть обработчиков событий концептуальной модели отсутствуют, так как два события E1 и E3, генерируемые системой отчетности учащихся, не требуют специальной обработки и могут обрабатываться агентами A1 и A2 в своем исходном виде, а E5 может потребляться всеми потребителями в своем исходном виде [2].

Рис. 3. Компоненты концептуальной архитектуры в сценарии

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

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

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

2. Сеть обработки событий и её реализация (EN), О. Этцион и Г.Шарон (O Etzion and G. Sharon), IBM Systems Journal, том 7, № 42 (2008 год).

Похожие статьи

Использование электронных учебных пособий в учреждениях.

Электронные учебные пособия выступают в качестве ассистентов преподавателей


Например, в электронных пособиях часто используются рабочие модели: так, на

К достоинствам использования электронных пособий во время выполнения практических.

Обзор технологий электронного обучения.

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

Особенности проектирования и разработки электронных.

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

Некоторые аспекты моделирования процесса формирования.

Высшие учебные заведения, несомненно, относятся к данному типу учреждений [3–5]. В наиболее общей формулировке задача составления расписания состоит в следующем: с помощью некоторого множества ресурсов или обслуживающих устройств должны быть.

Анализ инструментов разработки электронных курсов

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

Технология Wolfram CDF для создания электронного учебника по.

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

Разработка электронного учебника по дисциплине.

Таким образом, использование электронного учебника «Информатика» отвечает требованиям времени и дает положительный эффект при обучении; легкость тиражирования, разнообразие способов доступа к

Пример построения виртуальной 3D-модели учебного заведения.

Электронное обучение как средство реализации.

Именно в это время и получило развитие электронное обучение, которое на этом этапе развития служило «технически улучшенной формой дистанционного обучения» [1].

— обеспечивать формирование и корректировку индивидуальных учебных планов учащихся

Административные, коммуникативные, учебные инструменты.

В настоящее время, трудно недооценивать значимость способов организации учебного процесса, включающих передачу обучающимся учебной

Одним из ключевых понятий системы электронного обучения Moodle является курс, который состоит из блоков и модулей.

Экспертные системы: элективный курс (электронное учебное. )

Использование электронных учебных пособий в учреждениях. Электронные учебные пособия выступают в качестве ассистентов

В настоящее время выделены следующие классы моделей представления знаний [1]: ‒ продукционная модель; ‒ семантические сети; ‒ фреймы.

Анализ обработки событий в объектно-событийной модели документа

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

1. Введение

Одним из возможных способов увеличения эффективности работы с документами является использование интерактивных возможностей современных технологий [1]. Применительно к документообороту – это возможность создавать документы, которые сами проверяют правильность вводимых данных при заполнении и подсказывают, как исправить ошибки. По оценкам некоторых экспертов [13] до трети бумажных документов требуют повторного заполнения в связи с ошибками. Использование “умных” документов позволяет значительно сократить затраты времени и средств, поскольку автоматический контроль используется на самом раннем этапе – при создании документа. Заполнив и, например, распечатав такой документ, можно быть уверенным, что реквизиты указаны в соответствии с правилами и инструкциями. Существующие форматы представления, средства создания и манипулирования ЭД позволяют внедрять в документ исполняемый код. Таким образом, форма может нести в себе контроль целостности вводимых данных.

ГОСТ Р [3] определяет документ следующим образом: “зафиксированная на материальном носителе информация с реквизитами, позволяющими ее идентифицировать”, где реквизит документа – это “обязательный элемент оформления официального документа”. Далее под документом (документом в узком смысле слова, структурированным документом, формой) подразумевается именно так определенный объект.

Реквизиты документа в соответствии с ГОСТом делятся на следующие части:

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

— переменная часть реквизита документа — изменяемая часть реквизита документа, вносимая в бланк документа при его заполнении. Назовем ее динамической частью документа. Обычно, электронное представление позволяет использовать ЭВМ непосредственно для заполнения бланка. Поля ввода — элементы программного интерфейса, позволяющие изменять данные.

Один реквизит соответствует одному или нескольким полям ввода.

2. Объектно-событийная модель электронного документа.

Одной из широко используемых моделей документа является Document Object Model (DOM) [9], [10]. DOM – это интерфейс прикладного программирования (API) для “правильных” HTML [11] и XML документов [8], [12]. Он определяет логическую структуру документов, способы доступа и манипулирования данными. Используя DOM, программист может строить документы, перемещаться по структуре, добавлять, изменять и удалять элементы и их содержимое.

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

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

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

Логическая модель документа в другом широко распространненом формате формате PDF [6],[4] не соответствует DOM, но имеет очень много схожего. Документ может быть представлен как иерархия объектов с определенными свойствами и методами, точнее, внутри документа существует несколько различных иерархий. Документ представлен как дерево страниц. Каждая страница содержит описание визуального представления и набор аннотаций, часть которых может быть полями ввода.

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

Назовем контекстом исполнения конкретную программу-интерпретатор, обеспечивающую взаимодействие с пользователем и исполняющую код скрипта (Internet Explorer, Netscape, Acrobat Reader).

В результате действий пользователя или работы скриптов может наступить выполнение какого-то условия – такую ситуацию назовем событие. Если существует написанный пользователем обработчик этого события, то он исполняется, если такого нет, то система действует на свое усмотрение (в т. ч. порождая новые события). Таким образом, обработкой события назовем вызов пользовательского скрипта, а обработчиком события – непосредственно сам скрипт. Более подробно останавливаться на реализациях внутреннего механизма обработки и диспетчеризации событий контекстом не будем.

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

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

Можно рассматривать состояние ЭД, в виде совокупности значений всех реквизитов и вспомогательных переменных — т. е. всех переменных, участвующих в условиях переходов. Тогда изменение значения одной из управляющих переменных будет означать изменение состояния документа, а число состояний будет определяться максимально возможным количеством комбинаций значений управляющих переменных, возникающим при работе. Событийная система, которой является электронный документ в момент заполнения, сильно отличается от обычных программ – действиями пользователя могут быть созданы практически любые переходы между состояниями. Поведение же программы при непредусмотренном переходе может быть различным: от нарушения защиты памяти до продолжения функционирования с созданием различного рода побочных эффектов.

4. Формальная модель обработки событий.

Определение 1. Назовем событием выполнение некоторого условия.

Определение 2. Назовем обработчиком события процедуру, которая выполняется при наступлении события.

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

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

Далее рассматриваются только правильные обработчики.

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

множество упорядоченных вызовов обработчиков событий. Из i

Учебное пособие: Программирование графики и обработка событий

Методические указания к лабораторной работе

по курсу «Распределенные системы обработки информации»

Программирование графики и обработка событий

Цель работы

1. Познакомиться с библиотекой java.awt.

2. Научится обрабатывать события.

3. Освоить работу с управляющими компонентами и менеджерами размещения.

4. Применить полученные знания на практике

Задание для домашней подготовки

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

Задания к лабораторной работе

Задание 1

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

Задание 2

o Написать программу–калькулятор, реализующую графический интерфейс.

Содержание отчета

Отчет должен содержать:

1. Постановку задачи, решаемой отлаженной программой.

2. Руководство пользователя отлаженной программы, содержащее описание интерфейсов всех функций программы.

3. Листинг программы с необходимыми комментариями.

Контрольные вопросы

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

2. Какие менеджеры размещения компонентов вы знаете? В чем особенность каждого из них?

3. Измените программу так, чтобы метод getRez() вызывался при:

a) вводе текста в одно из текстовых полей

b) изменении состояния флажка (переключателей)

c) выборе одного из пунктов выпадающего списка

4. Как изменится работа программы, если внутри блока switch()<> не записывать операторы break.

5. Назовите два способа, которыми можно задать заголовок (title) окна.

Литература

1. Кен Арнольд, Джеймс Гослинг, Дэвид Холмс. Язык программирования Java™.

2. Официальный сайт Java — http://java.sun.com/ (есть раздел на русском языке с учебником).

3. Java™ 2 SDK, Standard Edition Documentation — http://java.sun.com/products/jdk/1.5/index.html.

4. Джеймс Гослинг, Билл Джой, Гай Стил. СпецификацияязыкаJava (TheJavaLanguageSpecification — http://www.javasoft.com/docs/books/jls/). Перевод на русский язык — http://www.uni-vologda.ac.ru/java/jls/index.html

5. Официальный сайт проекта Eclipse — http://www.eclipse.org/.

1. Дмитрий Рамодин. Начинаем программировать на языке Java.

2. Николай Смирнов. Java 2: Учебное пособие.

3. Картузов А. В. Программирование на языке Java.

4. Вязовик Н.А. Программирование на Java.

5. Алексей Литвинюк. Введение в интегрированную среду разработки Eclipse — http://lib.juga.ru/article/articleview/174/1/69/.

Приложение 1. Спецификация класса Calc.


importjava.awt.*; //подключение пакета с классами графических компонентов

importjava.awt.event.*; // подключение пакета с интерфейсами – “слушателями”

class Calc extends Frame implements ActionListener

//наследуем класс Frame (окно) и интерфейс “слушателя” события нажатия кнопки

TextFieldt1=newTextField(8); //размер поля – 8 символов

//… другие текстовые поля

Labell1=newLabel(«(double)»); //метка по умолчанию содержит текст «(double)»

Button b = new Button(«Получить результат»); //кнопка

Checkboxcb=newCheckbox(«+20%»);//флажок с названием

ch = newChoice();//конструктор выпадающего списка

ch.addItem(«+»);//добавляем пункты списка

//… другие пункты списка

setLayout(newFlowLayout()); //назначаем менеджер размещения компонентов (компоновщик)

add(l1);//выводим созданные компоненты на экран

public void windowClosing(WindowEvent e)<

show();//делает окно видимым

doublex, //значение из первого текстового поля

//… вторая переменная – значение второго текстового поля

x=newDouble(t1.getText()).doubleValue();//извлечение числа из первого текстового поля

case 0: Rez = x + /*вторая переменная*/; break;

if (cb.getState()) Rez*=1.2;//если флажок нажат, умножаем результат на 1.2

//записываем текст в поле (метку) результата с помощью метода setText(String.valueOf(Rez));

String s=new String(ex.getMessage());

//записываем текст в поле (метку) сообщения об ощибке с помощью метода setText(«Ошибка «+s);

>// окончание блока catch

>// окончание метода getRez()

public void actionPerformed(ActionEvent e)//реализацияметода actionPerformed

//(метод вызывается нажатием на кнопку b), см. выше

> //окончание класса Calc

Приложение 2. Иерархия классов AWT

На рис. 1 показана иерархия основных классов AWT. Основу ее составляют готовые компоненты: Button, Canvas, Checkbox, Choice, Container, Label, List, Scrollbar, TextArea, TextField, Menubar, Menu, PopupMenu, Menultem, CheckboxMenuItem. Если этого набора не хватает, то от класса Canvas можно породить собственные «тяжелые» компоненты, а от класса Component — «легкие» компоненты.

Основныеконтейнеры — этоклассы Panel, ScrollPane, Window, Frame, Dialog, FileDialog. Свои «тяжелые» контейнеры можно породить от класса Panel, а «легкие» — от класса Сontainer.

На рис. 1 также показаны и начальные классы иерархии библиотеки Swing — классы JComponent, JWindow, JFrame, JDialog, JApplet.

Рис. 1 Иерархия основных классов AWT

Приложение 3. Основные компоненты

Компонент Label

Компонент Label — это просто строка текста, оформленная как графический компонент для размещения в контейнере. Текст можно поменять только методом доступа setText(string text), но не вводом пользователя с клавиатуры или с помощью мыши.

Создается объект этого класса одним из трех конструкторов:

· Label () — пустой объект без текста;

· Label (string text) — объект с текстом text, который прижимается клевому краю компонента;

· Label (String text, int alignment) — объект с текстом text и определенным размещением в компоненте текста, задаваемого одной из трех констант: CENTER, LEFT, RIGHT.

Размещение можно изменить методом доступа setAlignment(int alignment).

Остальные методы позволяют получить текст getText() и размещение getAlignment ().

События

В классе Label происходят события классов Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent.

Компонент Button

Компонент Button — это кнопка стандартного для данной графической системы вида с надписью, умеющая реагировать на щелчок кнопки мыши — при нажатии она «вдавливается» в плоскость контейнера, при отпускании — становится «выпуклой».

Два конструктора Button () и Button (String label) создают кнопку без надписи и с надписью label соответственно.

Методы доступа getLabel() и setLabel (String label) позволяют получить и изменить надпись на кнопке.

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

События

Кроме событий класса Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent, при воздействии на кнопку происходит событие ActionEvent.

Компонент Checkbox

Компонент Checkbox — это надпись справа от небольшого квадратика, в котором в некоторых графических системах появляется галочка после щелчка кнопкой мыши — компонент переходит в состояние on. После следующего щелчка галочка пропадает — это состояние off. В других графических системах состояние on отмечается «вдавливанием» квадратика. В компоненте Checkbox состояния on/off отмечаются логическими значениями true/false соответственно.

Три конструктора Checkbox (), Checkbox (Stringlabel), Checkbox (Stringlabel, boolean state) создают компонент без надписи, с надписью label в состоянии off, и в заданном состоянии state.

Методы доступа getLabel(), setLabel (String label), getState(), setState (boolean state) возвращают и изменяют эти параметры компонента.

События

В классе Checkbox происходят события класса Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent, а при изменении состояния кнопки возникает событие ItemEvent.

В библиотеке AWT радиокнопки не образуют отдельный компонент. Вместо этого несколько компонентов Checkbox объединяются в группу с помощью объекта класса CheckboxGroup.

Класс CheckboxGroup

Класс CheckboxGroup очень мал, поскольку его задача — просто дать общее имя всем объектам Checkbox, образующим одну группу. В него входит один конструктор по умолчанию CheckboxGroup() и два метода доступа:

· getSelectedCheckbox(), возвращающий выбранный объект Checkbox;

· setSelectedCheckbox (Checkbox box), задающий выбор.

Как создать группу радиокнопок

Чтобы организовать группу радиокнопок, надо сначала сформировать объект класса CheckboxGroup, а затем создавать кнопки конструкторами

Checkbox(String label, CheckboxGroup group, boolean state)

Checkbox(String label, boolean state, CheckboxGroup group)

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

Только одна радиокнопка в группе может иметь состояние state = true.

Компонент Choice

Компонент Сhoice — это раскрывающийся список, один, выбранный, пункт (item) которого виден в поле, а другие появляются при щелчке кнопкой мыши на небольшой кнопке справа от поля компонента.

Вначале конструктором Choice() создается пустой список.

Затем, методом add (String text), в список добавляются новые пункты с текстом text. Они располагаются в порядке написания методов add() и нумеруются от нуля.

Вставить новый пункт в нужное место можно методом

insert (string text,int position).

Выбор пункта можно произвести из программы методом select (String text) или select(int position).

Удалить один пункт из списка можно методом remove (String text) или remove (int position), а все пункты сразу — методом removeAll().

Число пунктов в списке можно узнать методом getItemCount ().

Выяснить, какой пункт находится в позиции pos можно методом getItem(int pos), возвращающим строку.

Наконец, определение выбранного пункта производится методом getSelectedIndex(), возвращающим позицию этого пункта, или методом getSelectedItem(), возвращающим выделенную строку.

События

В классе Choice происходят события класса Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent, а при выборе пункта возникает событие ItemEvent.

Если надо показать на экране несколько пунктов списка, то в этом случае используется объект класса List.

Компонент TextField

Компонент TextField — это поле для ввода одной строки текста. Ширина поля измеряется в колонках (column). Ширина колонки — это средняя ширина символа в шрифте, которым вводится текст. Нажатие клавиши заканчивает ввод и служит сигналом к началу обработки введенного текста, т. е. при этом происходит событие ActionEvent.

В классе четыре конструктора:

· TextField() — создает пустое поле шириной в одну колонку;

· TextField(int columns) — создает пустое поле с числом колонок columns;

· TextField(String text) — создает поле с текстом text;

· TextField(String text, int columns) — создает поле с текстом text и числом колонок columns.

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

Данное поле ввода получается выполнением метода setEchoChar(char echo). Аргумент echo — это символ, который будет появляться в поле. Проверить, установлен ли эхо-символ, можно логическим методом echoCharisSet(), получить эхо-символ — методом getEchoChar ().

Чтобы вернуть поле ввода в обычное состояние, достаточно выполнить метод setEchoChar(0).

События

Кроме событий класса Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent, при изменении текста пользователем происходит событие TextEvent, а при нажатии на клавишу — событие ActionEvent.

Контейнер Framе


Контейнер Frame — это полноценное готовое окно со строкой заголовка, в которую помещены кнопки контекстного меню, сворачивания окна в ярлык и разворачивания во весь экран и кнопка закрытия приложения. Заголовок окна записывается в конструкторе или методом setTitle(String title).

На кнопке контекстного меню в левой части строки заголовка изображена дымящаяся чашечка кофе — логотип Java. Вы можете установить там другое изображение методом setIconImage(image icon), создав предварительно изображение icon в виде объекта класса image.

Все элементы окна Frame вычерчиваются графической оболочкой операционной системы по правилам этой оболочки. Окно Frame автоматически регистрируется в оконном менеджере графической оболочки и может перемещаться, менять размеры, сворачиваться в панель задач (task bar) с помощью мыши или клавиатуры, как «родное» окно операционной системы.

Создать окно типа Frame можно следующими конструкторами:

· Frame () — создает окно с пустой строкой заголовка;

· Frame (String title) — записывает аргумент title в строку заголовка.

Методы класса Frame осуществляют доступ к элементам окна, но также класс Frame наследует около двухсот методов классов Component, Container и Window. В частности, наследуется менеджер размещения по умолчанию — BorderLayout.

События

Кроме событий класса Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent, при изменении размеров окна, его перемещении или удалении с экрана, а также показа на экране происходит событие windowEvent.

Приложение 4. Менеджеры размещения.

Для того чтобы размещение компонентов в окне не нарушалось при движении, переносе и т.д. используются менеджеры размещения или компоновки (layout managers), называемые иногда просто компоновщиками.

Программист может воспользоваться стандартными менеджерами размещения или написать свои собственные, реализовав интерфейсы LayoutManager или LayoutManager2. К стандартным менеджерам размещения относятся:

Название: Программирование графики и обработка событий
Раздел: Рефераты по информатике
Тип: учебное пособие Добавлен 04:34:17 10 декабря 2010 Похожие работы
Просмотров: 16 Комментариев: 16 Оценило: 2 человек Средний балл: 5 Оценка: неизвестно Скачать
Класс Описание
null абсолютное позиционирование при размещении компонентов в контейнере
FlowLayout компоненты размещаются в контейнере один за другим: слева направо, сверху вниз
BorderLayout компоненты размещаются в контейнере в порядке сторон света – “Север”, “Восток”, “Юг”, “Запад”, “Центр”
GridLayout компоненты размещаются в контейнере в клетках таблицы; каждый элемент занимает одну клетку
GridBagLayout компоненты размещаются в контейнере в клетках таблицы; каждый элемент может занимать более одной клетки; является наиболее гибким компоновщиком
CardLayout одновременно доступен один компонент контейнера; идеальный менеджер компоновки для создания составных компонентов, похожих на “записные” книжки в Windows

Менеджеры размещения могут быть скомбинированы друг с другом.

По умолчанию в панелях и аплетах используется менеджер размещения FlowLayout, а в окнах и диалоговых окнах – BorderLayout.

Установка менеджера размещения для текущего контейнера осуществляется при помощи вызова:

Менеджер абсолютного размещения

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

Установка границ каждого компонента осуществляется при помощи метода:

компонент.setSize(координатаХ, координатаY, ширина, высота)

Компонент добавляется в контейнер при помощи метода:

Приведем пример использования менеджера размещения компонентов с абсолютным позиционированием.

Пример.1. Демонстрация использования менеджера размещения компонентов с абсолютным позиционированием

public class Absolute extends Frame<

Buttonb1 = newButton(«Cancel»),// Создадим две кнопки

b2 = new Button(«OK» );

public void Absolute()

setLayout(null);// Установим для окна менеджер абсолютного расположения

// Установим границы (расположение и размеры) для каждой кнопки

b1.setBounds( 50, 70, 50, 24);

b2.setBounds(110, 70, 50, 24);

// Добавим обе кнопки в окно

Менеджер FlowLayout

Наиболее просто поступает менеджер размещения FlowLayout. Он укладывает в контейнер один компонент за другим слева направо как кирпичи, переходя от верхних рядов к нижним. При изменении размера контейнера «кирпичи» перестраиваются. Компоненты поступают в том порядке, в каком они заданы в методах add().

В каждом ряду компоненты могут прижиматься к левому краю, если в конструкторе аргумент align равен FlowLayout.LEFT, к правому краю, если этот аргумент FlowLayout.RIGHT, или собираться в середине ряда, если FlowLayout.CENTER.

Между компонентами можно оставить промежутки (gap) по горизонтали hgap и вертикали vgap. Это задается в конструкторе:

FlowLayout(int align, int hgap, int vgap)

Второй конструктор задает промежутки размером 5 пикселов:

Третий конструктор определяет выравнивание по центру и промежутки 5 пикселов:

После формирования объекта эти параметры можно изменить методами:

setHgap(int hgap) setVgap(int vgap) setAlignment(int align)

Менеджер BorderLayout

Менеджер размещения BorderLayout делит контейнер на пять неравных областей, полностью заполняя каждую область одним компонентом. Области получили географические названия NORTH, SOUTH, WEST, EAST и CENTER.

Метод add() в случае применения BorderLayout имеет два аргумента: ссылку на компонент comp и область region, в которую помещается компонент — одну из перечисленных выше констант:

add(Component comp, String region)

Обычный метод add (Component comp) с одним аргументом помещает компонент в область CENTER.

В классе два конструктора:

· BorderLayout () — между областями нет промежутков;

· BorderLayout(int hgap int vgap) — между областями остаются горизонтальные hgap и вертикальные vgap промежутки, задаваемые в пикселах.

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

Рис. 2. Области размещения BorderLayout

Менеджер размещения BorderLayout кажется неудобным: он располагает не больше пяти компонентов, последние растекаются по всей области, области имеют странный вид. Но дело в том, что в каждую область можно поместить не компонент, а панель, и размещать компоненты на ней.

Менеджер GridLayout

Менеджер размещения GridLayout расставляет компоненты в таблицу с заданным в конструкторе числом строк rows и столбцов columns:

GridLayout(int rows, int columns)

Все компоненты получают одинаковый размер. Промежутков между компонентами нет. Второй конструктор позволяет задать промежутки между компонентами в пикселах по горизонтали hgap и вертикали vgap:

GridLayout(int rows, int columns, int hgap, int vgap)

Конструктор по умолчанию GridLayout() задает таблицу размером 0x0 без промежутков между компонентами. Компоненты будут располагаться в одной строке.

Компоненты размещаются менеджером GridLayout слева направо по строкам созданной таблицы в том порядке, в котором они заданы в методах add().

Нулевое количество строк или столбцов означает, что менеджер сам создаст нужное их число.

Рис. 3. Пример размещения кнопок менеджером GridLayout

Менеджер CardLayout

Менеджер размещения CardLayout своеобразен — он показывает в контейнере только один, первый (first), компонент. Остальные компоненты лежат под первым в определенном порядке как игральные карты в колоде. Их расположение определяется порядком, в котором написаны методы add(). Следующий компонент можно показать методом next(Container с), предыдущий — методом previous(Container с), Последний — методом last(Container с), первый — методом first(Container с). Аргумент этих методов — ссылка на контейнер, в который помещены компоненты, обычно this.

В классе два конструктора:

· СardLayout() — не отделяет компонент от границ контейнера;

· CardLayout(int hgap, int vgap) — задает горизонтальные hgap и вертикальные vgap поля.

Менеджер CardLayout позволяет организовать и произвольный доступ к компонентам. Метод add() для менеджера CardLayout имеет своеобразный вид:

add(Component comp, Object constraints)

Здесь аргумент constraints должен иметь тип String и содержать имя компонента. Нужный компонент с именем name можно показать методом:

show(Container parent, String name)

Рис. 4. Пример менеджера размещения CardLayout

Менеджер GridBagLayout

Менеджер размещения GridBagLayout расставляет компоненты наиболее гибко, позволяя задавать размеры и положение каждого компонента. Но он оказался очень сложным и применяется редко.

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

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

Класс GridBagConstraints содержит одиннадцать полей, определяющих размеры компонентов, их положение в контейнере и взаимное положение, и несколько констант — значений некоторых полей. Они перечислены в табл. 1. Эти параметры определяются конструктором, имеющим одиннадцать аргументов. Второй конструктор — конструктор по умолчанию — присваивает параметрам значения, заданные по умолчанию.

Таблица 1. Поля класса GridBagConstraints

Направление размещения компонента в контейнере. Константы:

CENTER, NORTH, EAST, NORTHEAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, и NORTHWEST; no умолчанию CENTER

Поле Значение
anchor
fill Растяжение компонента для заполнения ячейки. Константы: NONE, HORIZONTAL, VERTICAL, BOTH; ПОумолчаниюNONE
gridheight Количество ячеек в колонке, занимаемых компонентом. Целое типа int, по умолчанию 1. Константа REMAINDER означает, что компонент займет остаток колонки, RELATIVE — будет следующим по порядку в колонке
gridwidth Количество ячеек в строке, занимаемых компонентом. Целое типа int, по умолчанию 1. Константа REMAINDER означает, что компонент займет остаток строки, RELATIVE — будет следующим в строке по порядку
gridx Номер ячейки в строке. Самая левая ячейка имеет номер 0. По умолчанию константа RELATIVE, что означает: следующая по порядку
gridy Номер ячейки в столбце. Самая верхняя ячейка имеет номер 0. По умолчанию константа RELATIVE, что означает: следующая по порядку
insets Поля в контейнере. Объект класса insets; по умолчанию объект с нулями
ipadx, ipady Горизонтальные и вертикальные поля вокруг компонентов; по умолчанию 0
Пропорциональное растяжение компонентов при изменении размера контейнера; по умолчанию 0,0

Как правило, объект класса GridBagConstraints создается конструктором по умолчанию, затем значения нужных полей меняются простым присваиванием новых значений, например:

После создания объекта gbc класса GridBagConstraints менеджеру размещения указывается, что при помещении компонента comp в контейнер следует применять правила, занесенные в объект gbc. Для этого применяется метод

add(Component comp, GridBagConstraints gbc)

Итак, схема применения менеджера GridBagLayout такова:

setLayout(gbl); // Устанавливаем его в контейнер

// Задаем правила размещения по умолчанию

Button b2 = new Button(); // Создаемкомпонент

add(bl, с); // Помещаем компонент b2 в контейнерпо указанным правилам

Button b2 = new Button(); // Создаем следующий компонент

add(b2, с); // Помещаем в контейнер

Приложение 5. Обработка событий.

Java 2 использует хорошо структурированную, функционально полную и очень логичную модель обработки событий, впервые реализованную в JDK 1.1. Иерархия классов событий имеет вид:

Классы и интерфейсы для работы с делегированными событиями расположены в пакете java.awt.event (см. рисунок 5).

В классах событий существуют открытые методы:


Класс Метод Возвращаемые данные
EventObject Object getSource() объект, вызвавший события
String toString() строка, описывающая событие
AWTEvent int getID() идентификатор типа события
String paramString() строка параметров события
ActionEvent int getModifiers() состояние клавиш-модификаторов
String getActionCommand() название действия
AdjustmеntEvent int getValue() текущее значение, полученное из прокрутки
int getAdjustmentType() тип установки прокрутки, изменившей значения
Adjustable getAdjustable() ссылка на объект прокрутки, установивший значение
ItemEvent Object getItem() пункт списка, измененный данным событием
Container getContainer() объект, вызвавший данное событие
FocusEvent boolean isTemporary() истину, если фокус ввода данного объекта возобновляется самостоятельно
PaintEvent Graphics getGraphics() графический контекст для данного события
WindowEvent Window getWindow() ссылка на окно, которое вызвало данное событие
InputEvent boolean isShiftDown() истина, если нажата клавиша Shift
boolean isControlDown() истина, если нажата клавиша Control
boolean isMetaDown() истина, если нажата клавиша Meta
boolean isAltDown() истина, если нажата клавиша Alt
int getWhen() время в миллисекундах с того времени, как произошло данное событие
int getModifiers() состояние всех модификаторов клавиатуры
boolean isConsumed() истина, если событие обработано
KeyEvent int getKeyCode() код клавиши, вызвавшей событие
char getKeyChar() символ клавиши, вызвавшей событие
boolean isActionKey() истина, если клавиша, вызвавшая событие, является функциональной клавишей
MouseEvent int getX() текущая абсцисса указателя мыши при генерации данного события
int getY() текущая ордината указателя мыши при генерации данного события
Point getPoint() положение указателя мыши при генерации данного события
getClickCount() число нажатий на кнопку мыши при генерации данного события
isPopupTrigger() истина, если данное событие связано с переключателем всплывающего меню для текущей операционной платформы

Классы, ответственные за обработку событий в JDK 1.1, реализуют интерфейсы “прослушивания” событий (listeners):

Интерфейс Переопределяемые методы Описание
ActionListener произведено некоторое действие
AdjustmentListener adjustementValueChanged (AdjustmentEvent) изменилось значение в линии прокрутки
ComponentListener componentResized (ComponentEvent e) компонент изменил размер
компонент изменил расположение
компонент отображен
componentHidden (ComponentEvent e) компонент спрятан
ContainerListener
componentRemoved (ContainerEvent e) компонент убран из контейнера
FocusListener focusGained(FocusEvent e) компонент получил фокус ввода
focusLost (FocusEvent e) компонент потерял фокус ввода
ItemListener ItemStateChaged (ItemEvent e) изменился выделенный пункт выбора
KeyListener keyTyped(KeyEvent e) напечатан символ
keyPressed(KeyEvent e) нажата клавиша
keyReleased(KeyEvent e) нажатая клавиша отпущена
MouseListener mouseClicked(MouseEvent e) нажата и отпущена кнопка мыши
mousePressed(MouseEvent e) нажата кнопка мыши
mouseReleased(MouseEvent e) отпущена нажатая кнопка мыши
mouseEntered(MouseEvent e) указатель мыши вошел в область компонента
mouseExited(MouseEvent e) указатель мыши вышел из области компонента
MouseMotionListener mouseDragged(MouseEvent e) перемещен указатель мыши при нажатой кнопке мыши
mouseMoved(MouseEvent e) перемещен указатель мыши при не нажатой кнопке мыши
TextListener textValueChanged(TextEvent e) текстовое значение изменилось
WindowListener windowOpened(WindowEvent e) окно открыто
windowClosing(WindowEvent e) окно закрывается
windowClosed(WindowEvent e) окно закрыто
windowIconified(WindowEvent e) окно минимизировано
окно восстановило размеры после минимизации
окно активировано (является окном ввода информации)
окно перестало быть активным окном

Некоторым интерфейсам событий соответствуют открытые абстрактные классы-адаптеры, содержащие пустые методы для обработки событий:

Интерфейс Класс
ComponentListener ComponentAdapter
ContainerListener ContainerAdapter
FocusListener FocusAdapter
KeyListener KeyAdapter
MouseListener MouseAdapter
MouseMotionListener MouseMotionAdapter
MouseInputListener MouseInputAdapter
WindowListener WindowAdapted

К действиям относятся события, поступающие от компонентов:

Компонент Генерируемое событие
Button нажатие на кнопку мыши
MenuItem нажатие на кнопку мыши
List нажатие на кнопку мыши
нажатие на клавишу возврата каретки
TextField нажатие на клавишу возврата каретки

Управляющие компоненты регистрируют “прослушивание” событий при помощи методов вида:

и освобождаются от “прослушивания” событий при помощи соответствующих методов вида:

Метод для добавления “слушателя” события Componenet Container addContainerListener(ContainerListener l) Button addActionListener(ActionListener l) Checkbox addItemListener(ItemListener l) CheckboxMenuItem addItemListener(ItemListener l) Choice addItemListener(ItemListener l) List MenuItem addActionListener(ActionListener l) Scrollbar addAdjustnmentListener(AdjustmentListener l) TextComponent addTextListener(TextListener l) TextArea addActionListener(ActionListener l) Window addWindowListener(WindowListener l)

Приведем пример приложения, обрабатывающего событие ActionEvent

Пример работы с событием действия (ActionEvent)

public class FrameActionEvent extends Frame implements ActionListener<

Labell = newLabel();// Создадим метку для вывода сообщения

Buttonb = newButton(«OK»);// Создадим кнопку, генерирующую сообщение

setLayout(null);// Установим абсолютное размещение компонентов

setBackground(Color.lightGray);// Установим светло-серый фон

// Установим границы управляющих компонентов

l.setBounds(20, 10, 40, 20); // метки

b.setBounds(20, 40, 40, 20); // кнопки

// Зарегистрируем для кнопки “прослушивание” событий

СОБЫТИЯ в Java приложениях – Основные понятия

Обработка любого события (нажатие кнопки, щелчок мышью и др.) состоит в связывании события с методом, его обрабатывающим. Принцип обработки событий, начиная с Java 2, базируется на модели делегирования событий. В этой модели имеется блок прослушивания события (EventListener), который ждет поступления события определенного типа от источника, после чего обрабатывает его и возвращает управление. Источник – это объект, который генерирует событие, если изменяется его внутреннее состояние, например, изменился размер, изменилось значение поля, произведен щелчок мыши по форме или выбор значения из списка. После генерации объект-событие пересылается для обработки зарегистрированному в источнике блоку прослушивания как параметр его методов – обработчиков событий.

Блоки прослушивания Listener представляют собой объекты классов, реализующих интерфейсы прослушивания событий, определенных в пакете java.awt.event. Соответствующие методы, объявленные в используемых интерфейсах, необходимо явно реализовать при создании собственных классов прослушивания. Эти методы и являются обработчиками события. Передаваемый источником блоку прослушивания объект-событие является аргументом обработчика события. Объект класса – блока прослушивания события необходимо зарегистрировать в источнике методом

После этого объект-прослушиватель (Listener) будет реагировать именно на данное событие и вызывать метод «обработчик события». Такая логика обработки событий позволяет легко отделить интерфейсную часть приложения от функциональной, что считается необходимым при проектировании современных приложений. Удалить слушателя определенного события можно с помощью метода removeСобытиеListener().

Источником событий могут являться элементы управления: кнопки (JButton, JCheckbox, JRadioButton), списки, кнопки-меню. События могут генерироваться фреймами и апплетами, как mouse- и key-события. События генерируются окнами при развертке, сворачивании, выходе из окна. Каждый класс-источник определяет один или несколько методов addСобытиеListener() или наследует эти методы

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

Событийно-управляемое программирование

В основу Windows положен принцип событийного управления. Это значит, что и сама система, и приложения после запуска ожидают действий пользователя и реагируют наних заранее заданным образом. Любое действие пользователя (нажатие клавиши на клавиатуре, щелчок кнопкой мыши, перемещение мыши) называется событием. Структура программы, управляемой событиями, изобра­жена нарис. 14.1.

Рис. 14.1. Структура программы, управляемой событиями

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

Сообщения поступают в общую очередь, откуда распределяются по очередям приложений. Каждое приложение содержит цикл обработки сообщений, который выбирает сообщение из очереди и через операционную систему вызывает подпрограмму, предназначенную для его обработки (рис. 14.2). Таким образом Windows-приложение состоит из главной программы, обеспечивающей инициализанию и завершение приложения, цикла обработки сообщений и набора обработчиков событий.

Рис. 14.2. Структура Windows-приложения

Среда Visual Studio.NET содержит удобные средства разработки Windows-npи ложений, выполняющие вместо программиста рутинную работу — создание шаб лонов приложения и форм, заготовок обработчиков событий, организацию цик ла обработки сообщений и т. д. Рассмотрим эти средства.

Шаблон Windows-приложения

Создадим новый проект (File ► New ► Project), выбрав шаблон Windows Application (рис. 14.3). После более длительных раздумий, чем для консольного приложе­ния, среда сформирует шаблон Windows-приложения. Первое отличие, которое бросается в глаза, — вкладка заготовки формы Form1.cs[Design], расположенная в основной части экрана. Форма представляет собой окно и предназначена для размещения компонентов (элементов управления) — меню, текста, кнопок, спи­сков, изображений и т. д.

Рис. 14.3. Выбор шаблона проекта

Среда создает не только заготовку формы, но и шаблон текста приложения. Пе­рейти к нему можно, щелкнув в окне Solution Explorer (View ► Solution Explorer) правой кнопкой мыши на файле Form1.cs и выбрав в контекстном меню команду View Code. При этом откроется вкладка с кодом формы, который, за исключе­нием комментариев, приведен в листинге 14.1. Представлять себе, что написано в вашей программе, весьма полезно, поэтому давайте внимательно рассмотрим этот текст.

Листинг 14.1.Шаблон Windows-приложения

Модель обработки событий Java 1.1

Новая модель обработки событий представляет собой, по существу, модель обратных вызовов (callback). При создании GUI-элемента ему сообщается, какой метод или методы он должен вызывать при возникновении в нем определенного события (нажатия кнопки, мыши и т.п.). Эту модель очень легко использовать в C++, поскольку этот язык позволяет оперировать указателями на методы (чтобы определить обратный вызов, необходимо всего лишь передать указатель на функцию). Однако в Java это недопустимо (методы не являются объектами). Поэтому для реализации новой модели необходимо определить класс, реализующий некоторый специальный интерфейс. Затем можно передать экземпляр такого класса GUI-элементу, обеспечивая таким образом обратный вызов. Когда наступит ожидаемое событие, GUI-элемент вызовет соответствующий метод объекта, определенного ранее.

Модель обработки событий Java 1.1 используется как в пакете AWT, так и в JavaBeans API. В этой модели разным типам событий соответствуют различные классы Java. Каждое событие является подклассом класса java.util.EventObject. События пакета AWT, которые и рассматриваются в данной главе, являются подклассом java.awt.AWTEvent. Для удобства события различных типов пакета AWT (например, MouseEvent или АсtionEvent) помещены в новый пакет java.awt.event.

Для каждого события существует порождающий его объект, который можно получить с помощью метода getSource(), и каждому событию пакета AWT соответствует определенный идентификатор, который позволяет получить метод getid(). Это значение используется для того, чтобы отличать события различных типов, которые могут описываться одним и тем же классом событий. Например, для класса FocusEvent возможны два типа событий: FocusEvent.FOCUS_GAINED и FocusEvent.FOCUS_LOST. Подклассы событий содержат информацию, связанную с данным типом события. Например, в классе MouseEvent существуют методы getX(), getY() и getClickCount (). Этот класс наследует, в числе прочих, и методы getModifiers() и getWhen().

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

Источник события оповещает объект слушателя путем вызова специального метода и передачи ему объекта события (экземпляра подкласса EventObject). Для того чтобы источник мог вызвать данный метод, он должен быть реализован для каждого слушателя. Это объясняется тем, что все слушатели событий определенного типа должны реализовывать соответствующий интерфейс. Например, объекты слушателей событий ActionEvent должны реализовывать интерфейс ActionListener. В пакете Java.awt.event определены интерфейсы слушателей для каждого из определенных в нем типов событий (например, для событий MouseEvent здесь определено два интерфейса слушателей: MouseListener и MouseMotionListener). Все интерфейсы слушателей событий являются расширениями интерфейса java.util.EventListener. В этом интерфейсе не определяется ни один из методов, но он играет роль интерфейса-метки, в котором однозначно определены все слушатели событий как таковые.

В интерфейсе слушателя событий может определяться несколько методов. Например, класс событий, подобный MouseEvent, описывает несколько событий, связанных с мышью, таких как события нажатия и отпускания кнопки мыши. Эти события вызывают различные методы соответствующего слушателя. По установленному соглашению, методам слушателей событий может быть передан один единственный аргумент, являющийся объектом того события, которое соответствует данному слушателю. В этом объекте должна содержаться вся информация, необходимая программе для формирования реакции на данное событие. В таблице 6 приведены определенные в пакете java.awt.event типы событий, соответствующие им слушатели, а также методы, определенные в каждом интерфейсе слушателя.

Таблица 6. Типы событий, слушатели и методы слушателей в Java 1.1

Класс события Интерфейс слушателя Методы слушателя
ActionEvent ActionListener actionPerformed()
AdjustmentEvent AdjustmentListener adjustmentValueChanged()
ComponentEvent ComponentListener componentHidden() componentMoved() componentResized() Cor”componentShown()
ContainerEvent ContainerListener componentAdded() componentRemoved()
FocusEvent FocusListener focusGained() focusLost ()
ItemEvent ItemListener itemStateChanged()
KeyEvent KeyListener keyPressed() keyReleased() keyTyped()
MouseEvent MouseListener mouseClicked() mouseEntered() mouseExited() mousePressed() mouseReleased()
MouseMotionListener mouseDragged() mouseMoved()
TextEvent TextListener textValueChanged()
WindowEvent WindowListener windowActivated() windowClosed() windowClosing() windowDeactivated() windowDeiconified() windowlconified() windowOpened()

Для каждого интерфейса слушателей событий, содержащего несколько методов, в пакете java.awt.event определен простой класс-адаптер, который обеспечивает пустое тело для каждого из методов соответствующего интерфейса. Когда нужен только один или два таких метода, иногда проще получить подкласс класса-адаптера, чем реализовать интерфейс самостоятельно. При получении подкласса адаптера требуется лишь переопределить те методы, которые нужны, а при прямой реализации интерфейса необходимо определить все методы, в том числе и ненужные в данной программе. Заранее определенные классы-адаптеры называются так же, как и интерфейсы, которые они реализуют, но в этих названиях Listener заменяется на Adapter: MouseAdapter, WindowAdapter и т.д.

Как только реализован интерфейс слушателя или получены подклассы класса-адаптера, необходимо создать экземпляр нового класса, чтобы определить конкретный объект слушателя событий. Затем этот слушатель должен быть зарегистрирован соответствующим источником событий. В программах пакета AWT источником событий всегда является какой-нибудь элемент пакета. В методах регистрации слушателей событий используются стандартные соглашения об именах: если источник событий порождает события типа X, в нем существует метод addXListener () для добавления слушателя и метод removeXListener() для его удаления. Одной из приятных особенностей модели обработки событий Java 1.1 является возможность легко определять типы событий, которые могут порождаться данным элементом. Для этого следует просто просмотреть, какие методы зарегистрированы для его слушателя событий. Например, из описания API для объекта класса Button следует, что он порождает события ActionEvent. В таблице 7 приведен список элементов пакета AWT и событий, которые они порождают.

Таблица 7. Элементы пакета AWT и порождаемые ими события в Java1.1

Элемент Порождаемое событие Значение
Button ActionEvent Пользователь нажал кнопку
CheckBox ItemEvent Пользователь установил или сбросил флажок
CheckBoxMenuItem ItemEvent Пользователь установил или сбросил флажок рядом с пунктом меню
Choice ItemEvent Пользователь выбрал элемент списка или отменил его выбор
Component ComponentEvent Элемент либо перемещен, либо он стал скрытым,либо видимым
FocusEvent Элемент получил или потерял фокус ввода
KeyEvent Пользователь нажал или отпустил клавишу
MouseEvent Пользователь нажал или отпустил кнопку мыши, либо курсор мыши вошел или покинул область, занимаемую элементом, либо пользователь просто переместил мышь или переместил мышь при нажатой кнопке мыши
Container ContainerEvent Элемент добавлен в контейнер или удален из него
List ActionEvent Пользователь выполнил двойной щелчок мыши на элементе списка
ItemEvent Пользователь выбрал элемент списка или отменил выбор
MenuItem ActionEvent Пользователь выбрал пункт меню
Scrollbar AdjustmentEvent Пользователь осуществил прокрутку
TextComponent TextEvent Пользователь внес изменения в текст элемента
TextField ActionEvent Пользователь закончил редактирование текста элемента
Window WindowEvent Окно было открыто, закрыто, представлено в виде пиктограммы, восстановлено или требует восстановления

Рисование «каракулей» в Java 1.1

Модель обработки событий Java 1.1 является достаточно гибкой и предоставляет пользователю ряд возможностей для структуризации программы обработки событий. Первый из этих способов продемонстрирован в примере. В апплете данной версии реализованы интерфейсы MouseListener и MouseMotionListener, регистрирующие себя с помощью своих же методов addMouseListener() и addMouseMotionListener().

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble2 extends Applet implements
MouseListener, MouseMotionListener <
private int last_x, last_y;
public void init() <
// Сообщает данному апплету о том, какие объекты
// классов MouseListener и MouseMotionListener он должен оповещать
// о событиях, связанных с мышью и ее перемещением.
// Поскольку интерфейс реализуется в самом апплете,
// при этом будут вызываться методы апплета.
this.addMouseListener(this) ;
this.addMouseMotionListener(this);
>
// Метод интерфейса MouseListener. Вызывается при нажатии
// пользователем кнопки мыши.
public void mousePressed(MouseEvent e) <
last_x = e.getX();
last_y = e.getY();

>
// Метод интерфейса MouseMotionListener. Вызывается при
// перемещении мыши с нажатой кнопкой.
public void mouseDragged(MouseEvent e) <
Graphics g = this.getGraphics();
int x = e.getX(), y = e.getY();
g.drawLine(last_x, last_y, x, y);
last_x = x; last_y = y;

>
// Другие, не используемые методы интерфейса MouseListener.
public void mouseReleased(MouseEvent e) <;>
public void mouseClicked(MouseEvent e) <;>
public void mouseEntered(MouseEvent e) <;>
public void mouseExited(MouseEvent e) <;>
// Другой метод интерфейса MouseMotionListener.
public void mouseMoved(MouseEvent e) <;>
>

Рисуйте на здоровье (может у Вас талант) – Scribble2.html.

Рисование «каракулей» с использованием встроенных классов

Модель обработки событий Java 1.1 разработана с учетом того, чтобы хорошо сочетаться с другой новой особенностью Java 1.1: встроенными классами (глава, посвященная им, еще не написана ;-(). В следующем примере показано, как изменится данный апплет, если слушатели событий будут реализованы в виде анонимных встроенных классов. Обратите внимание на компактность данного варианта программы. Новая особенность, добавленная в апплет — кнопкаClear. Для этой кнопки зарегистрирован объект ActionListener, а сама она выполняет очистку экрана при наступлении соответствующего события.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble3 extends Applet <
int last_x, last_y;
public void init() <
// Определяет, создает и регистрирует объект MouseListener.
this.addMouseListener(new MouseAdapter() <
public void mousePressed(MouseEvent e) <
last_x = e.getX(); last_y = e.getY();

>);
// Определяет, создает и регистрирует объект MouseMotionListener.
this.addMouseMotionListener(new MouseMotionAdapter() <
public void mouseDragged(MouseEvent e) <
Graphics g = getGraphics();
int x = e.getX(), y= e.getY();
g.setColor(Color.black);
g.drawLine(last_x, last_y, x, y);
last_x = x; last_y = y;
>

>);
// Создает кнопку Clear.
Button b = new Button(«Clear»);
// Определяет, создает и регистрирует объект слушателя
// для обработки события, связанного с нажатием кнопки.
b.addActionListener(new ActionListener() <
public void actionPerformed(ActionEvent e) <
// стирание каракулей
Graphics g = getGraphics();

g.setColor(getBackground());
g.fillRect(0, 0, getSize().width, getSize().height);
>

>);
// Добавляет кнопку в апплет.
this.add(b);

Еще не нарисовались (может появились новые идеи) – Scribble3.html. Обратите внимание, что в этот пример порождает 3 вспомогательных класса : Scribble3$1,2,3.

Обработка и создание событий Handling and raising events

События в .NET основаны на модели делегата. Events in .NET are based on the delegate model. Модель делегата соответствует шаблону разработки наблюдателя, который позволяет подписчику зарегистрироваться у поставщика и получать от него уведомления. The delegate model follows the observer design pattern, which enables a subscriber to register with and receive notifications from a provider. Отправитель события отправляет уведомление о событии, а приемник событий получает уведомление и определяет ответ на него. An event sender pushes a notification that an event has happened, and an event receiver receives that notification and defines a response to it. В этом разделе описываются основные компоненты модели делегата, использование событий в приложениях и реализация событий в коде. This article describes the major components of the delegate model, how to consume events in applications, and how to implement events in your code.

Дополнительные сведения об обработке событий в приложениях Магазина Windows 8.x см. в разделе Общие сведения о событиях и перенаправленных событиях. For information about handling events in Windows 8.x Store apps, see Events and routed events overview.

События Events

Событие — это сообщение, посланное объектом, чтобы сообщить о совершении действия. An event is a message sent by an object to signal the occurrence of an action. Это действие может быть вызвано взаимодействием с пользователем, например при нажатии кнопки, или другой логикой программы, например изменением значения свойства. The action can be caused by user interaction, such as a button click, or it can result from some other program logic, such as changing a property’s value. Объект, вызывающий событие, называется отправителем событий. The object that raises the event is called the event sender. Отправителю событий не известен объект или метод, который будет получать (обрабатывать) созданные им события. The event sender doesn’t know which object or method will receive (handle) the events it raises. Обычно событие является членом отправителя событий; например, событие Click — член класса Button, а событие PropertyChanged — член класса, реализующего интерфейс INotifyPropertyChanged. The event is typically a member of the event sender; for example, the Click event is a member of the Button class, and the PropertyChanged event is a member of the class that implements the INotifyPropertyChanged interface.

Чтобы определить событие, необходимо использовать ключевое слово event в C# или Event в Visual Basic в сигнатуре класса события и задать тип делегата для события. To define an event, you use the C# event or the Visual Basic Event keyword in the signature of your event class, and specify the type of delegate for the event. Делегаты описаны в следующем разделе. Delegates are described in the next section.

Как правило, для вызова события добавляется метод, помеченный как protected и virtual (в C#) или Protected и Overridable (в Visual Basic). Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and Overridable (in Visual Basic). Назовите этот метод On EventName; например, OnDataReceived . Name this method On EventName; for example, OnDataReceived . Метод должен принимать один параметр, который определяет объект данных события, являющийся объектом типа EventArgs или производного типа. The method should take one parameter that specifies an event data object, which is an object of type EventArgs or a derived type. Этот метод предоставляется, чтобы производные классы могли переопределять логику для вызова события. You provide this method to enable derived classes to override the logic for raising the event. Производный класс должен вызывать метод On EventName базового класса, чтобы зарегистрированные делегаты получили событие. A derived class should always call the On EventName method of the base class to ensure that registered delegates receive the event.

В следующем примере показан способ объявления события ThresholdReached . The following example shows how to declare an event named ThresholdReached . Событие связано с делегатом EventHandler и возникает в методе OnThresholdReached . The event is associated with the EventHandler delegate and raised in a method named OnThresholdReached .

Делегаты Delegates

Делегат — это тип, содержащий ссылку на метод. A delegate is a type that holds a reference to a method. Делегат объявляется с сигнатурой, указывающей тип возвращаемого значения и параметры для методов, на которые он ссылается, и может содержать ссылки только на методы, соответствующие его сигнатуре. A delegate is declared with a signature that shows the return type and parameters for the methods it references, and it can hold references only to methods that match its signature. Таким образом, делегат эквивалентен указателю на строго типизированную функцию или обратному вызову. A delegate is thus equivalent to a type-safe function pointer or a callback. Объявления делегата достаточно для определения класса делегата. A delegate declaration is sufficient to define a delegate class.

У делегатов широкая область применения в .NET. Delegates have many uses in .NET. В контексте событий делегат — это посредник (или механизм, подобный указателю) между источником события и кодом, обрабатывающим событие. In the context of events, a delegate is an intermediary (or pointer-like mechanism) between the event source and the code that handles the event. Делегат связывается с событием за счет включения типа делегата в объявление события, как показано в примере в предыдущем разделе. You associate a delegate with an event by including the delegate type in the event declaration, as shown in the example in the previous section. Дополнительные сведения о делегатах см. в разделе, посвященном классу Delegate. For more information about delegates, see the Delegate class.

.NET предоставляет делегаты EventHandler и EventHandler для поддержки большинства сценариев событий. .NET provides the EventHandler and EventHandler delegates to support most event scenarios. Используйте делегат EventHandler для всех событий, не содержащих данных. Use the EventHandler delegate for all events that do not include event data. Используйте делегат EventHandler для событий, содержащих данные о событии. Use the EventHandler delegate for events that include data about the event. У этих делегатов нет типа возвращаемого значения. Они принимают два параметра (объект для источника события и объект для данных события). These delegates have no return type value and take two parameters (an object for the source of the event, and an object for event data).

Эти делегаты являются многоадресными, то есть в них могут храниться ссылки на несколько методов обработки событий. Delegates are multicast, which means that they can hold references to more than one event-handling method. Дополнительные сведения см. на справочной странице класса Delegate. For details, see the Delegate reference page. Делегаты позволяют гибко и точно управлять обработкой событий. Delegates provide flexibility and fine-grained control in event handling. Делегат выступает как диспетчер событий для класса, вызывающий событие за счет ведения списка зарегистрированных обработчиков для события. A delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event handlers for the event.

Для сценариев, в которых делегаты EventHandler и EventHandler не работают, можно определить собственный делегат. For scenarios where the EventHandler and EventHandler delegates do not work, you can define a delegate. Сценарии, для которых необходимо определять собственные делегаты, очень редки. Это бывает, например, при работе с кодом, не распознающим универсальные типы. Scenarios that require you to define a delegate are very rare, such as when you must work with code that does not recognize generics. При объявлении делегат необходимо пометить ключевым словом delegate в C# или Delegate в Visual Basic. You mark a delegate with the C# delegate and Visual Basic Delegate keyword in the declaration. В следующем примере показано, как объявить делегат с именем ThresholdReachedEventHandler . The following example shows how to declare a delegate named ThresholdReachedEventHandler .

Данные событий Event data

Данные, связанные с событием, могут быть предоставлены с помощью класса данных события. Data that is associated with an event can be provided through an event data class. .NET предоставляет множество классов данных событий, которые можно использовать в приложениях. .NET provides many event data classes that you can use in your applications. Например, класс SerialDataReceivedEventArgs — класс данных события SerialPort.DataReceived. For example, the SerialDataReceivedEventArgs class is the event data class for the SerialPort.DataReceived event. В .NET имена всех классов данных событий оканчиваются ключевым словом EventArgs . .NET follows a naming pattern of ending all event data classes with EventArgs . Определить, какой класс данных события связан с событием, можно по делегату этого события. You determine which event data class is associated with an event by looking at the delegate for the event. Например, делегат SerialDataReceivedEventHandler содержит класс SerialDataReceivedEventArgs в качестве одного из своих параметров. For example, the SerialDataReceivedEventHandler delegate includes the SerialDataReceivedEventArgs class as one of its parameters.

Класс EventArgs является базовым типом для всех классов данных событий. The EventArgs class is the base type for all event data classes. Класс EventArgs используется также, если событие не содержит связанных данных. EventArgs is also the class you use when an event does not have any data associated with it. При создании события, которое лишь уведомляет другие классы о том, что что-то произошло, и не передает никаких данных, используйте класс EventArgs в качестве второго параметра в делегате. When you create an event that is only meant to notify other classes that something happened and does not need to pass any data, include the EventArgs class as the second parameter in the delegate. Если данные не предоставляются, можно передать значение EventArgs.Empty. You can pass the EventArgs.Empty value when no data is provided. Делегат EventHandler содержит класс EventArgs в качестве параметра. The EventHandler delegate includes the EventArgs class as a parameter.

Если требуется создать пользовательский класс данных события, создайте класс, производный от класса EventArgs, а затем укажите все члены, необходимые для передачи данных, связанных с событием. When you want to create a customized event data class, create a class that derives from EventArgs, and then provide any members needed to pass data that is related to the event. В большинстве случаев следует использовать схему именования .NET и завершать имя класса данных события ключевым словом EventArgs . Typically, you should use the same naming pattern as .NET and end your event data class name with EventArgs .

В следующем примере показан класс данных события с именем ThresholdReachedEventArgs . The following example shows an event data class named ThresholdReachedEventArgs . Он содержит свойства, относящиеся только к вызываемому событию. It contains properties that are specific to the event being raised.

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

Для обработки события в приемнике события необходимо определить метод обработчика события. To respond to an event, you define an event handler method in the event receiver. Этот метод должен соответствовать сигнатуре делегата обрабатываемого события. This method must match the signature of the delegate for the event you are handling. В обработчике событий выполняются действия, необходимые при возникновении события, например сбор данных, введенных пользователем при нажатии кнопки. In the event handler, you perform the actions that are required when the event is raised, such as collecting user input after the user clicks a button. Чтобы получать уведомления при возникновении события, метод обработчика события должен быть подписан на событие. To receive notifications when the event occurs, your event handler method must subscribe to the event.


В следующем примере показан метод обработчика события c_ThresholdReached , который соответствует сигнатуре делегата EventHandler. The following example shows an event handler method named c_ThresholdReached that matches the signature for the EventHandler delegate. Метод подписывается на событие ThresholdReached . The method subscribes to the ThresholdReached event.

Обработчики статических и динамических событий Static and dynamic event handlers

.NET позволяет подписчикам регистрироваться для получения уведомлений о событиях как статически, так и динамически. .NET allows subscribers to register for event notifications either statically or dynamically. Обработчики статических событий действуют в течение всего жизненного цикла класса, события которого они обрабатывают. Static event handlers are in effect for the entire life of the class whose events they handle. Обработчики динамических событий активируются и деактивируются во время выполнения программы, обычно в ответ на определенную условную логику программы. Dynamic event handlers are explicitly activated and deactivated during program execution, usually in response to some conditional program logic. Например, они могут использоваться, если уведомления о событиях требуются только в определенных условиях, либо приложение предоставляет несколько обработчиков событий и выбор конкретного обработчика зависит от условий среды выполнения. For example, they can be used if event notifications are needed only under certain conditions or if an application provides multiple event handlers and run-time conditions define the appropriate one to use. В примере в предыдущем разделе показано, как динамически добавлять обработчик события. The example in the previous section shows how to dynamically add an event handler. Дополнительные сведения см. в разделах события (в Visual Basic) и события (в C#). For more information, see Events (in Visual Basic) and Events (in C#).

Создание нескольких событий Raising multiple events

Если класс создает несколько событий, компилятор создает одно поле для каждого экземпляра делегата события. If your class raises multiple events, the compiler generates one field per event delegate instance. При большом количестве событий стоимость хранения одного поля на делегата может оказаться неприемлемой. If the number of events is large, the storage cost of one field per delegate may not be acceptable. Для таких случаев .NET предоставляет свойства события, которые можно использовать вместе с другой структурой данных для хранения делегатов события. For those situations, .NET provides event properties that you can use with another data structure of your choice to store event delegates.

Свойства событий состоят из объявлений событий и методов доступа к событиям. Event properties consist of event declarations accompanied by event accessors. Методы доступа к событиям — это определяемые пользователем методы, добавляющие или удаляющие экземпляры делегата события из структуры данных хранения. Event accessors are methods that you define to add or remove event delegate instances from the storage data structure. Обратите внимание, что использование свойств события снижает быстродействие по сравнению с полями события, поскольку перед вызовом каждого делегата события его необходимо извлечь. Note that event properties are slower than event fields, because each event delegate must be retrieved before it can be invoked. Необходимо найти компромисс между памятью и скоростью. The trade-off is between memory and speed. Если ваш класс определяет много событий, которые вызываются нечасто, необходимо реализовать свойства событий. If your class defines many events that are infrequently raised, you will want to implement event properties. Дополнительные сведения см. в разделе Практическое руководство. Обработка нескольких событий с помощью их свойств. For more information, see How to: Handle Multiple Events Using Event Properties.

Модели обработки событий

Несмотря на существенные изменения механизма обработки событий в AWT, Java1.1 поддерживает обратную совместимость с моделью обработки событий, принятой в Java 1.0. Однако такая совместимость относится к типу «все или ничего» — эти две модели настолько отличаются друг от друга, что их невозможно использовать в одном приложении одновременно.

Модель обработки событий Java 1.0

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

Каждый компонент может обрабатывать события, заместив определенные методы, вызываемые используемой по умолчанию реализацией метода handleEvents класса Component. Этот метод вызывается с объектом класса Event, описывающего все возможные типы событий. Наиболее часто используемые события, например, те, что связаны с мышью и клавиатурой, диспетчеризируются другим методам класса Component.

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

  • mouseEnter вызывается в том случае, когда мышь входит в компонент.
  • mouseExit вызывается при выходе мыши из области компонента.
  • mouseMove вызывается при перемещении мыши в области компонента.
  • mouseDown вызывается при нажатии кнопки мыши.
  • mouseDrag вызывается при перемещении мыши с нажатой кнопкой.
  • mouseUp вызывается при отпускании кнопки мыши.

Аналогично, keyDown и keyUp вызываются при каждом нажатии и отпускании клавиши. Событие передается методу вместе с кодом нажатой клавиши. Событие можно проверить, чтобы посмотреть, нажаты ли в данный момент какие либо клавиши-модификаторы, для этой цели можно также пользоваться методами shiftDown, controlDown и metaDown. В классе Event определены десятки констант, позволяющих использовать символические имена, например, PGUP и HOME.

Наконец, для работы со специальными событиями, например, с обратными вызовами (callback) из компонентов Button, Scrollbar и Menu, вам придется замещать метод action. Этот метод вызывается с исходным событием и со вторым параметром, который представляет собой компонент пользовательского интерфейса, создавший это событие. Вы должны проверить этот объект, разобраться, какой из компонентов послал вам событие, после чего передать управление соответствующему данному компоненту обработчику. Для того, чтобы перед приведением типа проверить, принадлежит ли объект к определенному классу, например, к классу Button, вы можете использовать оператор instanceof.

А вот и пример на обработку событий. Мы добавили объект Label к примеру с игрой в «пятнашки», а также заместили метод action для того, чтобы обрабатывать события, возникающие при нажатии кнопок. Точно такой же механизм можно использовать для управления вводом через любой из подклассов Component.

Элементы и связанные с ними события

В таблице 5 для каждого элемента пакета AWT перечислены типы событий, которые он может порождать. В первом столбце таблицы указан тип элемента, а во втором — тип соответствующего ему события. Тип события представляет собой константу, которая записывается в переменную id объекта класса Event.

В столбцах с третьего по седьмой указано, устанавливаются ли значения переменных -when (время события), х (координата х курсора мыши), у (координата у курсора мыши), key (нажатая кнопка) и modifiers (специальные клавиши, которые нажаты при этом) для данного события. Если в столбце стоит точка, значит, событие устанавливает значение соответствующей переменной. В восьмом столбце объяснено, что порождает данное событие и приведено значение, которое записывается в переменной arg объекта класса Event.

События, перечисленные для элементов класса Component, применимы ко всем подклассам класса java.awt. Component, а события, приведенные для элементов класса window, относятся как к подклассам класса window, так и к классам Dialog и Frame.

Таблица 5. Элементы AWT и события Java 1.0, которые порождаются ими

Элемент Тип события (id) w
h
e
r
e
x y k
e
y
m
o
d
s
Смысл события Тип и значение переменной arg
Button ACTION_EVENT Пользователь нажал кнопку String: обозначение кнопки
Checkbox ACTION_EVENT Пользователь активизировал флажок Boolean: новое состояние флажка
Choice (список выбора) ACTION_EVENT Пользователь выбрал элемент списка String: обозначение выбранного элемента
Element (элемент) GOT_FOCUS Получение фокуса ввода не используется
Element (элемент) KEY_ACTION * * * * * Пользователь нажал функциональную клавишу не используется, поскольку key содержит константу клавиши
Element (элемент) KEY_ACTION_ RELEASE * * * * * Пользователь отпустил функциональную клавишу не используется, поскольку key содержит константу клавиши
Element (элемент) KEY_PRESS * * * * * Пользователь нажал клавишу не используется, поскольку key содержит ASCII-код клавиши
Element (элемент) KEY_RELEASE * * * * * Пользователь отпустил клавишу не используется, поскольку key содержит ASCII-код клавиши
Element (элемент) LOST_FOCUS Потеря фокуса ввода не используется
Element (элемент) MOUSE_ENTER> * * * Курсор мыши попал в область объекта класса Component не используется
Element (элемент) MOUSE_EXIT * * * Курсор мыши вышел из области объекта класса Component не используется
Element (элемент) MOUSE_DOWN * * * * Пользователь нажал кнопку мыши не используется
Element (элемент) MOUSE_UP * * * * Пользователь отпустил кнопку мыши не используется
Element (элемент) MOUSE_MOVE * * * * Пользователь переместил мышь не используется
Element (элемент) MOUSE_DRAG * * * * Пользователь переместил мышь при нажатой кнопке мыши не используется
List (список) ACTION_EVENT Пользователь выполнил двойной щелчок мыши на элементе списка String: обозначение выбранного элемента
List (список) LIST_SELECT Пользователь выбрал элемент списка Integer: индекс выбранного элемента
List (список) LIST_DESELECT Пользователь убрал выделение с определенного элемента Integer: индекс элемента
Menu Item (меню) ACTION_EVENT Пользователь выбрал пункт меню String: обозначение выбранного пункта
Scrollbar (полоса прокрутки) SCROLL_LINE_UP Пользователь осуществил прокрутку вверх на строку Integer: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки) SCROLL_LINE_DOWN Пользователь осуществил прокрутку вниз на строку Integer: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки) SCROLL_PAGE_UP Пользователь осуществил прокрутку вверх на страницу Integer: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки) SCROLL_PAGE_DOWN Пользователь осуществил прокрутку вниз на страницу Integer: позиция, до которой осуществляется прокрутка
Scrollbar (полоса прокрутки) SCROLL_ABSOLUTE Пользователь переместил ползунок полосы прокрутки Integer: позиция, до которой осуществляется прокрутка
Text Field (текст) ACTION_EVENT Пользователь ввел текст и нажал [Enter]. String: введенный текст
Window (окно) WINDOW_DESTROY Окно закрыто не используется
Window (окно) WINDOW_ICONIFY Окно представлено в виде пиктограммы не используется
Window (окно) WINDOW_DEICONIFY Окно восстановлено не используется
Window (окно) WINDOW_MOVED * * Окно перемещено не используется

Рисование «каракулей» в Java 1.0

Классический апплет, в котором используется модель обработки событий Java 1.0. В нем методы mouseDown() и mouseDragO переопределены таким образом, чтобы пользователь имел возможность рисовать «каракули» с помощью мыши. Также переопределен метод keyDown(), чтобы при нажатии клавиши [С] экран очищался, и метод action(), чтобы экран очищался после щелчка на кнопке Clear.

Модель обработки событий Java 1.1

Новая модель обработки событий представляет собой, по существу, модель обратных вызовов (callback). При создании GUI-элемента ему сообщается, какой метод или методы он должен вызывать при возникновении в нем определенного события (нажатия кнопки, мыши и т.п.). Эту модель очень легко использовать в C++, поскольку этот язык позволяет оперировать указателями на методы (чтобы определить обратный вызов, необходимо всего лишь передать указатель на функцию). Однако в Java это недопустимо (методы не являются объектами). Поэтому для реализации новой модели необходимо определить класс, реализующий некоторый специальный интерфейс. Затем можно передать экземпляр такого класса GUI-элементу, обеспечивая таким образом обратный вызов. Когда наступит ожидаемое событие, GUI-элемент вызовет соответствующий метод объекта, определенного ранее.

Модель обработки событий Java 1.1 используется как в пакете AWT, так и в JavaBeans API. В этой модели разным типам событий соответствуют различные классы Java. Каждое событие является подклассом класса java.util.EventObject. События пакета AWT, которые и рассматриваются в данной главе, являются подклассом java.awt.AWTEvent. Для удобства события различных типов пакета AWT (например, MouseEvent или АсtionEvent) помещены в новый пакет java.awt.event.

Для каждого события существует порождающий его объект, который можно получить с помощью метода getSource(), и каждому событию пакета AWT соответствует определенный идентификатор, который позволяет получить метод getid(). Это значение используется для того, чтобы отличать события различных типов, которые могут описываться одним и тем же классом событий. Например, для класса FocusEvent возможны два типа событий: FocusEvent.FOCUS_GAINED и FocusEvent.FOCUS_LOST. Подклассы событий содержат информацию, связанную с данным типом события. Например, в классе MouseEvent существуют методы getX(), getY() и getClickCount (). Этот класс наследует, в числе прочих, и методы getModifiers() и getWhen().

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

Источник события оповещает объект слушателя путем вызова специального метода и передачи ему объекта события (экземпляра подкласса EventObject). Для того чтобы источник мог вызвать данный метод, он должен быть реализован для каждого слушателя. Это объясняется тем, что все слушатели событий определенного типа должны реализовывать соответствующий интерфейс. Например, объекты слушателей событий ActionEvent должны реализовывать интерфейс ActionListener. В пакете Java.awt.event определены интерфейсы слушателей для каждого из определенных в нем типов событий (например, для событий MouseEvent здесь определено два интерфейса слушателей: MouseListener и MouseMotionListener). Все интерфейсы слушателей событий являются расширениями интерфейса java.util.EventListener. В этом интерфейсе не определяется ни один из методов, но он играет роль интерфейса-метки, в котором однозначно определены все слушатели событий как таковые.

В интерфейсе слушателя событий может определяться несколько методов. Например, класс событий, подобный MouseEvent, описывает несколько событий, связанных с мышью, таких как события нажатия и отпускания кнопки мыши. Эти события вызывают различные методы соответствующего слушателя. По установленному соглашению, методам слушателей событий может быть передан один единственный аргумент, являющийся объектом того события, которое соответствует данному слушателю. В этом объекте должна содержаться вся информация, необходимая программе для формирования реакции на данное событие. В таблице 6 приведены определенные в пакете java.awt.event типы событий, соответствующие им слушатели, а также методы, определенные в каждом интерфейсе слушателя.

Таблица 6. Типы событий, слушатели и методы слушателей в Java 1.1

Класс события Интерфейс слушателя Методы слушателя
ActionEvent ActionListener actionPerformed()
AdjustmentEvent AdjustmentListener adjustmentValueChanged()
ComponentEvent ComponentListener componentHidden()
componentMoved()
componentResized()
componentShown()
ContainerEvent ContainerListener componentAdded()
componentRemoved()
FocusEvent FocusListener focusGained()
focusLost()
ItemEvent ItemListener itemStateChanged()
KeyEvent KeyListener keyPressed()
keyReleased()
keyTyped()
MouseEvent MouseListener mouseClicked()
mouseEntered()
mouseExited()
mousePressed()
mouseReleased()
MouseMotionListener mouseDragged()
mouseMoved()
TextEvent TextListener textValueChanged()
WindowEvent WindowListener windowActivated()
windowClosed()
windowClosing()
windowDeactivated()
windowDeiconified()
windowlconified()
windowOpened()

Для каждого интерфейса слушателей событий, содержащего несколько методов, в пакете java.awt.event определен простой класс-адаптер, который обеспечивает пустое тело для каждого из методов соответствующего интерфейса. Когда нужен только один или два таких метода, иногда проще получить подкласс класса-адаптера, чем реализовать интерфейс самостоятельно. При получении подкласса адаптера требуется лишь переопределить те методы, которые нужны, а при прямой реализации интерфейса необходимо определить все методы, в том числе и ненужные в данной программе. Заранее определенные классы-адаптеры называются так же, как и интерфейсы, которые они реализуют, но в этих названиях Listener заменяется на Adapter: MouseAdapter, WindowAdapter и т.д.

Как только реализован интерфейс слушателя или получены подклассы класса-адаптера, необходимо создать экземпляр нового класса, чтобы определить конкретный объект слушателя событий. Затем этот слушатель должен быть зарегистрирован соответствующим источником событий. В программах пакета AWT источником событий всегда является какой-нибудь элемент пакета. В методах регистрации слушателей событий используются стандартные соглашения об именах: если источник событий порождает события типа X, в нем существует метод addXListener () для добавления слушателя и метод removeXListener() для его удаления. Одной из приятных особенностей модели обработки событий Java 1.1 является возможность легко определять типы событий, которые могут порождаться данным элементом. Для этого следует просто просмотреть, какие методы зарегистрированы для его слушателя событий. Например, из описания API для объекта класса Button следует, что он порождает события ActionEvent. В таблице 7 приведен список элементов пакета AWT и событий, которые они порождают.

Таблица 7. Элементы пакета AWT и порождаемые ими события в Java1.1

Элемент Порождаемое событие Значение
Button ActionEvent Пользователь нажал кнопку
CheckBox ItemEvent Пользователь установил или сбросил флажок
CheckBoxMenuItem ItemEvent Пользователь установил или сбросил флажок рядом с пунктом меню
Choice ItemEvent Пользователь выбрал элемент списка или отменил его выбор
Component ComponentEvent Элемент либо перемещен, либо он стал скрытым,либо видимым
FocusEvent Элемент получил или потерял фокус ввода
KeyEvent Пользователь нажал или отпустил клавишу
MouseEvent Пользователь нажал или отпустил кнопку мыши, либо курсор мыши вошел или покинул область, занимаемую элементом, либо пользователь просто переместил мышь или переместил мышь при нажатой кнопке мыши
Container ContainerEvent Элемент добавлен в контейнер или удален из него
List ActionEvent Пользователь выполнил двойной щелчок мыши на элементе списка
ItemEvent Пользователь выбрал элемент списка или отменил выбор
MenuItem ActionEvent Пользователь выбрал пункт меню
Scrollbar AdjustmentEvent Пользователь осуществил прокрутку
TextComponent TextEvent Пользователь внес изменения в текст элемента
TextField ActionEvent Пользователь закончил редактирование текста элемента
Window WindowEvent Окно было открыто, закрыто, представлено в виде пиктограммы, восстановлено или требует восстановления

Рисование «каракулей» в Java 1.1

Модель обработки событий Java 1.1 является достаточно гибкой и предоставляет пользователю ряд возможностей для структуризации программы обработки событий. Первый из этих способов продемонстрирован в примере. В апплете данной версии реализованы интерфейсы MouseListener и MouseMotionListener, регистрирующие себя с помощью своих же методов addMouseListener() и addMouseMotionListener().

Рисование «каракулей» с использованием встроенных классов

Модель обработки событий Java 1.1 разработана с учетом того, чтобы хорошо сочетаться с другой новой особенностью Java 1.1: встроенными классами (глава, посвященная им, еще не написана ;-(). В следующем примере показано, как изменится данный апплет, если слушатели событий будут реализованы в виде анонимных встроенных классов. Обратите внимание на компактность данного варианта программы. Новая особенность, добавленная в апплет — кнопка Clear. Для этой кнопки зарегистрирован объект ActionListener, а сама она выполняет очистку экрана при наступлении соответствующего события.

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

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

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

— это строка, определяющая тип действия, вызвавшего событие. Тип «mousemove», например, означает, что пользователь переместил указатель мыши. Тип «keydown» означает, что была нажата клавиша на клавиатуре. А тип «load» означает, что завершилась загрузка документа (или какого-то другого ресурса) из сети. Поскольку тип события — это просто строка, его иногда называют именем события.

— это объект, в котором возникло событие или с которым это событие связано. Когда говорят о событии, обычно упоминают тип и цель события. Например, событие «load» объекта Window или событие «click» элемента . Самыми типичными целями событий в клиентских приложениях на языке JavaScript являются объекты Window, Document и Element, но некоторые типы событий могут происходить и в других типах объектов.

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

— это объект, связанный с определенным событием и содержащий информацию об этом событии. Объекты событий передаются функции обработчика события в виде аргумента (кроме IE8 и более ранних версий, где объект события доступен только в виде глобальной переменной event). Все объекты событий имеют свойство type, определяющее тип события, и свойство target, определяющее цель события.

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

— это процесс, в ходе которого браузер решает, в каких объектах следует вызвать обработчики событий. В случае событий, предназначенных для единственного объекта (таких как событие «load» объекта Window), надобность в их распространении отсутствует. Однако, когда некоторое событие возникает в элементе документа, оно распространяется, или «всплывает», вверх по дереву документа.

Если пользователь щелкнет мышью на гиперссылке, событие «mousemove» сначала будет возбуждено в элементе , определяющем эту ссылку. Затем оно будет доставлено вмещающим элементам: возможно, элементу

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

Регистрация обработчиков событий

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

Дело осложняется тем, что каждый прием имеет две версии. Свойство обработчика события можно установить в программном коде на языке JavaScript или в элементе документа, определив соответствующий атрибут непосредственно в разметке HTML. Регистрация обработчиков вызовом метода может быть выполнена стандартным методом с именем addEventListener(), который поддерживается всеми браузерами, кроме IE версии 8 и ниже, и другим методом, с именем attachEvent(), поддерживаемым всеми версиями IE до IE9.

Установка свойств обработчиков событий

Самый простой способ зарегистрировать обработчик события заключается в том, чтобы присвоить свойству целевого объекта события желаемую функцию обработчика. По соглашению свойства обработчиков событий имеют имена, состоящие из слова «on», за которым следует имя события: onclick, onchange, onload, onmouseover и т.д. Обратите внимание, что эти имена свойств чувствительны к регистру и в них используются только строчные символы, даже когда имя типа события состоит из нескольких слов (например «readystatechange»). Ниже приводятся два примера регистрации обработчиков событий:

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

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

Установка атрибутов обработчиков событий

Свойства обработчиков событий в элементах документа можно также устанавливать, определяя значения атрибутов в соответствующих HTML-тегах. В этом случае значение атрибута должно быть строкой программного кода на языке JavaScript. Этот программный код должен быть не полным объявлением функции обработчика события, а только ее телом. То есть реализация обработчика события в разметке HTML не должна заключаться в фигурные скобки и предваряться ключевым словом function. Например:

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

Некоторые типы событий предназначены для браузера в целом, а не для какого-то конкретного элемента документа. Обработчики таких событий в языке JavaScript регистрируются в объекте Window. В разметке HTML они должны помещаться в тег , но браузер зарегистрирует их в объекте Window. Ниже приводится полный список таких обработчиков событий, определяемых проектом спецификации HTML5:

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

addEventListener()

В стандартной модели событий, поддерживаемой всеми браузерами, кроме IE версии 8 и ниже, целью события может быть любой объект — включая объекты Window и Document и все объекты Elements элементов документа — определяющий метод с именем addEventListener(), с помощью которого можно регистрировать обработчики событий для этой цели.

Метод addEventListener() принимает три аргумента. Первый — тип события, для которого регистрируется обработчик. Тип (или имя) события должен быть строкой и не должен включать префикс «on», используемый при установке свойств обработчиков событий. Вторым аргументом методу addEventListener() передается функция, которая должна вызываться при возникновении события указанного типа. В последнем аргументе методу addEventListener() передается логическое значение. Обычно в этом аргументе передается значение false. Если передать в нем значение true, функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в другой фазе распространения события.

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

Следующий фрагмент регистрирует два обработчика события «click» в элементе . Обратите внимание на различия двух используемых приемов:

Вызов метода addEventListener() со строкой «click» в первом аргументе никак не влияет на значение свойства onclick. Во фрагменте, приведенном выше, щелчок на кнопке приведет к выводу двух диалоговых окон alert(). Но важнее то, что метод addEventListener() можно вызвать несколько раз и зарегистрировать с его помощью несколько функций-обработчиков для одного и того же типа события в том же самом объекте. При появлении события в объекте будут вызваны все обработчики, зарегистрированные для этого типа события, в порядке их регистрации.

Многократный вызов метода addEventListener() для одного и того же объекта с теми же самыми аргументами не дает никакого эффекта — функция-обработчик регистрируется только один раз и повторные вызовы не влияют на порядок вызова обработчиков.

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

Internet Explorer версии ниже IE9 не поддерживает методы addEventListener() и removeEventListener(). В версии IE5 и выше определены похожие методы, attachEvent() и detachEvent(). Поскольку модель событий в IE не поддерживает фазу перехвата, методы attachEvent() и detachEvent() принимают только два аргумента: тип события и функцию обработчика, при этом в первом аргументе методам в IE передается имя свойства обработчика с префиксом «on», а не тип события без этого префикса.

Вызов обработчиков событий

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

Аргумент обработчика событий

При вызове обработчика событий ему обычно (за одним исключением, о котором рассказывается ниже) передается объект события в виде единственного аргумента. Свойства объекта события содержат дополнительную информацию о событии. Свойство type, например, определяет тип возникшего события.

В IE версии 8 и ниже обработчикам событий, зарегистрированным установкой свойства, объект события при вызове не передается. Вместо этого объект события сохраняется в глобальной переменной window.event. Для переносимости обработчики событий можно оформлять, как показано ниже, чтобы они использовали переменную window.event при вызове без аргумента:

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

При регистрации обработчика события посредством HTML-атрибута браузер преобразует строку с программным кодом на языке JavaScript в функцию. Браузеры, отличные от IE, создают функцию с единственным аргументом event. В IE создается функция, не принимающая аргументов. Если в таких функциях использовать идентификатор event, он будет ссылаться на window.event. В любом случае обработчики событий, определяемые в разметке HTML, могут ссылаться на объект события, используя идентификатор event.

Контекст обработчиков событий

Когда обработчик событий регистрируется установкой свойства, это выглядит как определение нового метода элемента документа:

Поэтому нет ничего удивительного, что обработчики событий вызываются (с одним исключением, касающимся IE, которое описывается ниже) как методы объектов, в которых они определены. То есть в теле обработчика событий ключевое слово this ссылается на цель события.

В обработчиках ключевое слово this ссылается на целевой объект, даже когда они были зарегистрированы с помощью метода addEventListener(). Однако, к сожалению, это не относится к методу attachEvent(): обработчики, зарегистрированные с помощью метода attachEvent(), вызываются как функции, и в них ключевое слово this ссылается на глобальный (Window) объект. Эту проблему можно решить следующим способом:

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

Возвращаемые значения обработчиков

Значение, возвращаемое обработчиком события, зарегистрированным установкой свойства объекта или с помощью HTML-атрибута, следует учитывать. Обычно возвращаемое значение false сообщает браузеру, что он не должен выполнять действия, предусмотренные для этого события по умолчанию.

Например, обработчик onclick кнопки отправки формы может вернуть false, чтобы предотвратить отправку формы браузером. (Это может пригодиться, если ввод пользователя не прошел проверку на стороне клиента.) Аналогично обработчик события onkeypress поля ввода может фильтровать ввод с клавиатуры, возвращая false при вводе недопустимых символов.

Также важно значение, возвращаемое обработчиком onbeforeunload объекта Window. Это событие генерируется, когда браузер выполняет переход на другую страницу. Если этот обработчик вернет строку, она будет выведена в модальном диалоговом окне, предлагающем пользователю подтвердить свое желание покинуть страницу.

Важно понимать, что учитываются значения, возвращаемые обработчиками событий, только если обработчики зарегистрированы посредством установки свойств. Обработчики, зарегистрированные с помощью addEventListener() или attachEvent() вместо этого должны вызывать метод preventDefault() или устанавливать свойство returnValue объекта события.

Отмена событий

Значение, возвращаемое обработчиком события, зарегистрированным как свойство, можно использовать для отмены действий, выполняемых браузером по умолчанию в случае этого события. В браузерах, поддерживающих метод addEventListener(), отменить выполнение действий по умолчанию можно также вызовом метода preventDefault() объекта события. Однако в IE, версии 8 и ниже, тот же эффект достигается установкой свойства returnValue объекта события в значение false.

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

Текущий проект модуля «DOM Events 3» определяет в объекте Event свойство с именем defaultPrevented. Оно пока поддерживается не всеми браузерами, но суть его в том, что при обычных условиях оно имеет значение false и принимает значение true только в случае вызова метода preventDefault().

Отмена действий, по умолчанию связанных с событием, — это лишь одна из разновидностей отмены события. Имеется также возможность остановить распространение события. В браузерах, поддерживающих метод addEventListener(), объект события имеет метод stopPropagation(), вызов которого прерывает дальнейшее распространение события. Если в том же целевом объекте будут зарегистрированы другие обработчики этого события, то остальные обработчики все равно будут вызваны, но никакие другие обработчики событий в других объекта не будут вызваны после вызова метода stopPropagation().

В IE версии 8 и ниже метод stopPropagation() не поддерживается. Вместо этого объект события в IE имеет свойство cancelBubble. Установка этого свойства в значение true предотвращает распространение события.

Текущий проект спецификации «DOM Events 3» определяет в объекте Event еще один метод — метод с именем stopImmediatePropagation(). Подобно методу stopPropagation(), он предотвращает распространение события по любым другим объектам. Но кроме того, он также предотвращает вызов любых других обработчиков событий, зарегистрированных в том же объекте.

Илон Маск рекомендует:  Что такое парсер (граббер)
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL