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




кастомные $listeners (5)

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

GWTP - «Полная модель-представление-презентатор для упрощения вашего следующего проекта GWT».

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

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

благодаря


События в целом:

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

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

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

Тогда ты можешь:

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

События в GWT:

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

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

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

Шаг 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 :

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 создается, он принимает один аргумент в своем конструкторе. Каждое событие имеет источник происхождения, и этот параметр будет использоваться в качестве источника для всех событий, отправляемых этим менеджером обработчика. В этом примере источником событий является MessageChecker .

Метод fireEvent определяется в интерфейсе HasHandlers и отвечает за отправку событий. Как вы можете видеть, он просто использует диспетчер обработчика для отправки (пожара) и события.

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

Шаг 4: Принять приемники событий с отправителями событий

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

MessageChecker checker = new MessageChecker();
MessageDisplayer displayer = new MessageDisplayer();
checker.addMessageReceivedEventHandler(displayer);

Теперь все события, отправленные с помощью checker будут получены displayer .

Шаг 5: Отправить события

Чтобы отправить событие, MessageChecker должен создать экземпляр события и отправить его с использованием метода fireEvent . Это можно сделать с newMailReceived метода 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);
    }

}

Надеюсь, это понятно и поможет :)


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

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

Я хотел начать с ответа Хилбринда Бувокпама, потому что он был новее. Но у меня возникло несколько проблем. 1) Этот ответ сделал ссылку на автобус событий. Четный автобус - это глобальная переменная, принадлежащая основной программе. Неясно, как библиотека виджета может получить доступ к этому. 2) Я не начинал с нуля. Я расширил библиотечный код GWT. Чтобы выполнить эту работу, мне пришлось начинать с класса GwtEvent, а не класса Event.

Ответ Петра, по сути, правильный, но он был очень долгим. Мой класс (косвенно) расширяет класс Widget 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);
    }

Мое новое событие почти точно совпадает с классом событий Piotr, показанным выше. Стоит отметить одно. Я начал с 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);
    }
}

Поскольку этот вопрос и ответ от 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"));

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

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


Событие «EditingControlShowing» не срабатывает при изменении значения флажка. Поскольку стиль отображения ячейки флажка не изменяется.

Обходной путь, который я использовал, приведен ниже. (Я использовал событие CellContentClick)

    private void gGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (string.Compare(gGridView1.CurrentCell.OwningColumn.Name, "CheckBoxColumn") == 0)
        {
            bool checkBoxStatus = Convert.ToBoolean(gGridView1.CurrentCell.EditedFormattedValue);
            //checkBoxStatus gives you whether checkbox cell value of selected row for the
            //"CheckBoxColumn" column value is checked or not. 
            if(checkBoxStatus)
            {
                //write your code
            }
            else
            {
               //write your code
            }
        }
    }

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







events gwt