Добавление слушателей событий

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

Интерфейс слушателя

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

Подписка на события

Существуют различные интерфейсы слушателей в GWT. Например, интерфейс ClickListener является простым обработчиком событий кликов мыши. Он содержит только один метод, onClick (Widget). Этот метод будет вызван, когда пользователь нажимает на виджет, который в свою очередь опубликовал событие кликов мыши. Один из таких виджетов является класс Button. Для просмотра этого в действии, вернемся к нашему примеру StockWatcher. У нас уже есть кнопки для добавления акций в список. Теперь мы будем обрабатывать события кликов посредством реализации интерфейса ClickListener.

Для этого нам необходимо знать точное название метода - addClickListener (ClickListener). Давайте двигаться вперед, и доработаем код метода onModuleLoad():

public void onModuleLoad() {
    // set up stock list watch list
    stocksFlexTable.setText(0, 0, "Symbol");
    stocksFlexTable.setText(0, 1, "Price");
    stocksFlexTable.setText(0, 2, "Change");
    stocksFlexTable.setText(0, 3, "Remove");
    // set up event listeners for adding a new stock
    addButton.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        addStock();
      }
    });

    // assemble Add Stock panel
    addPanel.add(newSymbolTextBox);
    addPanel.add(addButton);

    // assemble main panel
    mainPanel.add(stocksFlexTable);
    mainPanel.add(addPanel);
    mainPanel.add(lastUpdatedLabel);

    // add the main panel to the HTML element with the id "stockList"
    RootPanel.get("stockList").add(mainPanel);

    // move cursor focus to the text box
    newSymbolTextBox.setFocus(true);
  }

  private void addStock() {
    // executed when user clicks the addButton
  }

Вам также необходимо добавить пару новых инструкций импорта в StockWatcher.java:

import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Widget;

Вы заметите, что мы использовали анонимный внутренний класс для реализации ClickListener. В нем мы определили метод onClick (Widget), в котором делегируем вызов метода, addStock (). В данном методе мы будем проверять написание имени акции и добавлять ее в общий список акций.

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

public class ListenerExample extends Composite implements ClickListener {
  private FlowPanel fp = new FlowPanel();
  private Button b1 = new Button("Button 1");
  private Button b2 = new Button("Button 2");
  public ListenerExample() {
    initWidget(fp);
    fp.add(b1);
    fp.add(b2);
    b1.addClickListener(this);
    b2.addClickListener(this);
  }
  public void onClick(Widget sender) {
    if (sender == b1) {
    // handle b1 being clicked
    } else if (sender == b2) {
    // handle b2 being clicked
    }
  }
}

Адаптеры слушателей

Сейчас, вернемся к StockWatcher. Как только мы реализуем addStock () в следующем разделе, пользователь сможет нажать на кнопку Добавить, чтобы добавить акцию в список. Для удобства, давайте также дадим ему возможность использовать клавиатуру и при нажатии ENTER внутри текстового поля newSymbolTextBox, акция будет добавляться в список. Чтобы сделать это, мы подпишемся на события клавиатуры для виджета newSymbolTextBox , для этого мы вызовем его метод addKeyboardListener() и передадим в качестве параметра ссылку на реализацию KeyboardListener.
Глядя на KeyboardListener интерфейс, мы видим, что он содержит три метода:
  • onKeyDown(Widget, char, int) Вызывается когда пользователь нажимает на «физическую» клавишу.
  • onKeyPress(Widget, char, int) Вызывается когда пользователь печатает текст на клавиатуре.
  • onKeyUp (Widget, char, int) Вызывается когда пользователь отпускает на «физическую» клавишу.
В нашем примере это нам действительно нужен всего лишь метод onKeyDown (Widget, char, int) слушателя KeyboardListener. Что нам нужно, так это класс, который позволяет нам принимать конкретные события в которых мы заинтересованы и игнорировать все остальные. Как выясняется, GWT имеет класс - адаптер для этой цели. Адаптеры просто пустые реализации того или иного интерфейса. Просто создадим подкласс класса адаптера и реализуем прием события на которые хотим подписаться.
Для StockWatcher, мы добавим инструкцию импорта KeyboardListenerAdapter:

import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
Реализуем его подкласс и передадим ссылку в вызове метода addKeyboardListener(KeyboardListener) в onModuleLoad() следующим образом:

// set up event listeners for adding a new stock
addButton.addClickListener(new ClickListener() {
  public void onClick(Widget sender) {
    addStock();
  }
});

newSymbolTextBox.addKeyboardListener(new KeyboardListenerAdapter() {
  @Override public void onKeyDown(Widget sender, char keyCode, int modifiers) {
    if (keyCode == KEY_ENTER) {
      addStock();
    }
  }
}
);

// assemble Add Stock panel
addPanel.add(newSymbolTextBox);
addPanel.add(addButton);


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

Комментариев нет:

Отправить комментарий