События в целом:
События всегда отправляются для информирования о чем-либо (например, об изменении состояния). Давайте возьмем ваш пример с человеком и стеной. Здесь можно представить, что есть игра, в которой пользователь может ходить как человек в лабиринте. Каждый раз, когда пользователь ударяется о стену, он должен быть проинформирован о столкновении, чтобы он мог на него отреагировать (например, стена может выглядеть как разрушенная стена). Это может быть достигнуто путем отправки события столкновения каждый раз, когда обнаруживается столкновение со стеной. Это событие отправляется человеком, и каждый объект в системе, заинтересованный в событии, получает его и может соответствующим образом реагировать на него. Объекты, которые хотят получать события, должны зарегистрироваться как заинтересованные в событии.
Вот как события в целом работают в каждой системе или структуре (не только в GWT). Чтобы отправлять и получать события в таких системах, необходимо определить:
- Что отправлено (как выглядят события)
- Кто получает события (получатели событий)
- Кто отправляет события (отправители событий)
Тогда вы можете:
- Регистрация получателей событий, которые хотят получать события
- Отправка событий
События в GWT:
Здесь я покажу пример использования пользовательских событий в GWT. Я буду использовать пример системы, которая отвечает за проверку почтового ящика и сообщать пользователю, если есть новые письма. Предположим, что в системе есть как минимум 2 компонента:
- средство проверки сообщений, отвечающее за проверку почтового ящика, и
- средство отображения сообщений, отвечающее за отображение новых писем
Средство проверки сообщений отправляет события при получении нового сообщения, и средство просмотра сообщений получает эти события.
Шаг 1: Определить события
Информация о новом письме будет отправлена как экземпляр класса MessageReceivedEvent
. Класс содержит новое письмо (для простоты предположим, что это просто String
).
Полный исходный код этого класса представлен ниже (комментарий к нему находится ниже исходного кода).
public class MessageReceivedEvent extends GwtEvent<MessageReceivedEventHandler> {
public static Type<MessageReceivedEventHandler> TYPE = new Type<MessageReceivedEventHandler>();
private final String message;
public MessageReceivedEvent(String message) {
this.message = message;
}
@Override
public Type<MessageReceivedEventHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(MessageReceivedEventHandler handler) {
handler.onMessageReceived(this);
}
public String getMessage() {
return message;
}
}
MessageReceivedEventHandler
- это интерфейс, который представляет приемники событий. Не беспокойтесь сейчас, это будет обсуждаться позже.
Каждый класс, представляющий событие GWT, должен расширять GwtEvent
класс. Этот класс содержит два абстрактных метода, которые должны быть реализованы: getAssociatedType
и dispatch
. Однако в каждом классе событий они обычно реализуются очень похожим образом.
Класс хранит информацию о полученном сообщении (см. Конструктор). Каждый получатель события может получить его, используя метод getMessage
.
Шаг 2. Определение получателей событий
Каждый тип события в GWT связан с интерфейсом, представляющим приемники этого типа события. В GWT приемники называются обработчиками. В этом примере интерфейс получателя событий для MessageReceivedEvent
будет называться MessageReceivedEventHandler
. Исходный код ниже:
public interface MessageReceivedEventHandler extends EventHandler {
void onMessageReceived(MessageReceivedEvent event);
}
Каждый обработчик должен расширять интерфейс EventHandler
. Он также должен определять метод, который будет вызываться при возникновении события (он должен принимать хотя бы один параметр - событие). Здесь метод называется onMessageReceived
. Каждый получатель может реагировать на событие, реализуя этот метод.
Единственный получатель события в примере - это MessageDisplayer
component:
public class MessageDisplayer implements MessageReceivedEventHandler {
@Override
public void onMessageReceived(MessageReceivedEvent event) {
String newMessage = event.getMessage();
// display a new message
// ...
}
}
Шаг 3: Определить отправителей событий
В этом примере единственным отправителем события является компонент, отвечающий за проверку почты - EventChecker
:
public class MessageChecker implements HasHandlers {
private HandlerManager handlerManager;
public MessageChecker() {
handlerManager = new HandlerManager(this);
}
@Override
public void fireEvent(GwtEvent<?> event) {
handlerManager.fireEvent(event);
}
public HandlerRegistration addMessageReceivedEventHandler(
MessageReceivedEventHandler handler) {
return handlerManager.addHandler(MessageReceivedEvent.TYPE, handler);
}
}
Каждый отправитель событий должен реализовывать интерфейс HasHandlers
.
Самый важный элемент здесь - это поле HandlerManager
. В GWT HandlerManager
как подсказывает название, управляет обработчиками событий (получателями событий). Как было сказано в начале, каждый получатель событий, который хочет получать события, должен зарегистрироваться как заинтересованный. Для этого и нужны менеджеры-обработчики. Они позволяют регистрировать обработчики событий и отправлять определенное событие каждому зарегистрированному обработчику событий.
Когда создается HanlderManager
, он принимает один аргумент в своем конструкторе. Каждое событие имеет источник происхождения, и этот параметр будет использоваться в качестве источника для всех событий, отправляемых этим менеджером обработчика. В примере это this
, поскольку источником событий является MessageChecker
.
Метод fireEvent
определен в интерфейсе HasHandlers
и отвечает за отправку событий. Как вы можете видеть, он просто использует диспетчер обработчиков для отправки (огня) и события.
addMessageReceivedEventHandler
используется получателями событий для регистрации их как заинтересованных в получении событий. Снова для этого используется менеджер обработчиков.
Шаг 4. Связывание получателей событий с отправителями событий
Когда все определено, получатели событий должны зарегистрироваться в отправителях событий. Обычно это делается при создании объектов:
MessageChecker checker = new MessageChecker();
MessageDisplayer displayer = new MessageDisplayer();
checker.addMessageReceivedEventHandler(displayer);
Теперь все события, отправленные checker
, будут получены displayer
.
Шаг 5. Отправка событий
Чтобы отправить событие, MessageChecker
должен создать экземпляр события и отправить его, используя метод fireEvent
. Это можно сделать методом newMailReceived
:
public class MessageChecker implements HasHandlers {
// ... not important stuff omitted
public void newMailReceived() {
String mail = ""; // get a new mail from mailbox
MessageReceivedEvent event = new MessageReceivedEvent(mail);
fireEvent(event);
}
}
Надеюсь понятно и поможет :) 1111 *