Пользовательские события GWT

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

У меня есть 2 класса блок и класс man. Когда человек сталкивается с блоком, человек запускает событие (onCollision ()), а затем класс block слушает это событие.

спасибо

4 ответов


событий в целом:

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

вот как события работают в целом в каждой системе или структуре (не только в GWT). Для отправки и получения событий в таких системах необходимо определить:

  1. что отправляется (как выглядят события)
  2. кто получает события (приемники событий)
  3. кто отправляет события (отправители событий)

затем вы можете:

  1. Регистрация приемников событий, которые хотят получать события
  2. отправить события

события в GWT:

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

  • message checker отвечает за проверку почтового ящика и
  • message displayer отвечает за отображение новых сообщений

Message checker отправляет события при получении новой почты и message displayer получает эти события.

Шаг 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 . Исходный код приведен ниже:

public interface MessageReceivedEventHandler extends EventHandler {
    void onMessageReceived(MessageReceivedEvent event);
}

каждый обработчик должен продлить EventHandler интерфейс. Он также должен определить метод, который будет вызываться при возникновении события (он должен принимать хотя бы один параметр - событие). Здесь метод называется onMessageReceived. Каждый приемник может реагировать на событие, реализуя этот метод.

единственный приемник событий в Примере -MessageDisplayer компоненты:

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 интерфейс.

самым важным элементом здесь является


поскольку этот вопрос и ответ от Piotr GWT добавили поддержку немного другого способа создания пользовательских событий. Эта реализация события является конкретной сборкой, которая будет использоваться с EventBus GWT в пакете com.google.web.bindery.event.shared. Пример построения пользовательского события для GWT 2.4:

import com.google.web.bindery.event.shared.Event;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;

/**
 * Here is a custom event. For comparison this is also a MessageReceivedEvent.
 * This event extends the Event from the web.bindery package.
 */
public class MessageReceivedEvent extends Event<MessageReceivedEvent.Handler> {

    /**
     * Implemented by methods that handle MessageReceivedEvent events.
     */
    public interface Handler {
        /**
         * Called when an {@link MessageReceivedEvent} event is fired.
         * The name of this method is whatever you want it.
         *
         * @param event an {@link MessageReceivedEvent} instance
         */
        void onMessageReceived(MessageReceivedEvent event);
    }

    private static final Type<MessageReceivedEvent.Handler> TYPE =
        new Type<MessageReceivedEvent.Handler>();

    /**
     * Register a handler for MessageReceivedEvent events on the eventbus.
     * 
     * @param eventBus the {@link EventBus}
     * @param handler an {@link MessageReceivedEvent.Handler} instance
     * @return an {@link HandlerRegistration} instance
     */
    public static HandlerRegistration register(EventBus eventBus,
        MessageReceivedEvent.Handler handler) {
      return eventBus.addHandler(TYPE, handler);
    }    

    private final String message;

    public MessageReceivedEvent(String message) {
        this.message = message;
    }

    @Override
    public Type<MessageReceivedEvent.Handler> getAssociatedType() {
        return TYPE;
    }

    public String getMessage() {
        return message;
    }

    @Override
    protected void dispatch(Handler handler) {
        handler.onMessageReceived(this);
    }
}

событие используется следующим образом:

чтобы зарегистрировать обработчик для этого события с помощью eventbus, вызовите метод статического регистра в MessageReceivedEvent класс:

MessageReceivedEvent.register(eventbus, new MessageReceivedEvent.Handler() {
   public void onMessageReceived(MessageReceivedEvent event) {
     //...do something usefull with the message: event.getMessage();
   }
});

теперь, чтобы запустить событие на вызов eventbus fireEvent С недавно построенным событием:

eventBus.fireEvent(new MessageReceivedEvent("my message"));

другая реализация может быть найдена в собственном GWT EntityProxyChange класс событий. Эта реализация использует альтернативный вариант EventBus. Он использует возможность добавления обработчиков, привязанных к определенному источнику, через addHandlerToSource и может быть вызвано через eventBus.fireEventFromSource.

реализация события, приведенная здесь, также более подходит при работе с GWT деятельность.


Я создал свой собственный виджет, расширив составной класс GWT. Я хотел создать свое собственное событие в этом классе. Я хотел, чтобы события были доступны редактору WindowBuilder GWT.

я узнал много из ответов на этой странице, но мне пришлось внести некоторые изменения.

Я хотел начать с ответа Hilbrand Bouwkamp, потому что он был новее. Но я столкнулся с парой проблем. 1) этот ответ сделал ссылку на шину событий. Автобус even является глобальным переменная, принадлежащая основной программе. Неясно, как библиотека виджетов может получить доступ к этому. 2) я не начинал с нуля. Я расширял код библиотеки GWT. Чтобы сделать эту работу, я должен был начать с класса GwtEvent, а не С класса Event.

ответ Петра по существу правильный, но он был очень длинным. Мой класс (косвенно) расширяет класс виджета GWT. Виджет заботится о многих деталях, таких как создание объекта HandlerManager. (Я посмотрел сквозь исходный код, и именно так работают стандартные виджеты, а не с помощью EventBus.)

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

public class TrackBar extends Composite {

    public HandlerRegistration addValueChangedHandler(TrackBarEvent.Handler handler)
    {
        return addHandler(handler, TrackBarEvent.TYPE); 
    }   

    private void fireValueChangedEvent()
    {
        final TrackBarEvent e = new TrackBarEvent(value);
        fireEvent(e);
    }

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

import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;

public class TrackBarEvent extends GwtEvent< TrackBarEvent.Handler >
{
    public interface Handler extends EventHandler {
        void onTrackBarValueChanged(TrackBarEvent event);
    }

    static final Type<TrackBarEvent.Handler> TYPE =
            new Type<TrackBarEvent.Handler>();

    private final int value;

    public TrackBarEvent(int value) {
        this.value = value;
    }

    @Override
    public Type<TrackBarEvent.Handler> getAssociatedType() {
        return TYPE;
    }

    public int getValue() {
        return value;
    }

    public TrackBar getTrackBar()
    {
        return (TrackBar)getSource();
    }

    @Override
    protected void dispatch(Handler handler) {
        handler.onTrackBarValueChanged(this);
    }
}

Если вы используете GWTP framework поверх GWT, обратитесь к этот стек.

GWTP это " полная модель-представление-presenter framework для упрощения вашего следующего проекта GWT."