Как объяснено в Реализация слушателя событий, события автоматически ставятся в очередь в стандартных компонентах, которые запускают события. Кастомный компонент, с другой стороны, должен вручную ставить события в очередь из своего метода decode
, если он запускает события.
Выполнение декодирования объясняет, как поставить событие в очередь в MapComponent
, используя метод decode
. В этом разделе объясняется, как написать класс, представляющий событие клика на карту, и как написать метод, который обрабатывает это событие.
Как объясняется в Пояснении к странице Facelets, атрибут actionListener
тега bookstore:map
указывает на класс MapBookChangeListener
, Метод processAction
класса слушателя обрабатывает событие клика на карту изображения. Вот метод processAction
:
@Override
public void processAction(ActionEvent actionEvent)
throws AbortProcessingException {
AreaSelectedEvent event = (AreaSelectedEvent) actionEvent;
String current = event.getMapComponent().getCurrent();
FacesContext context = FacesContext.getCurrentInstance();
String bookId = books.get(current);
context.getExternalContext().getSessionMap().put("bookId", bookId);
}
Когда JavaServer Faces вызывает этот метод, он передаёт объект ActionEvent
, который представляет событие, сгенерированное путём клика на карту изображения. Затем он преобразует его в объект AreaSelectedEvent
(см. tut-install/examples/case-studies/dukes-bookstore/src/java/dukesbookstore/listeners/AreaSelectedEvent.java
). Затем этот метод получает MapComponent
, связанный с событием. Затем он получает значение атрибута current
объекта MapComponent
, который указывает выбранную область. Затем метод использует значение атрибута current
для получения значения идентификатора книги из объекта HashMap
, который создаётся где-то в другом месте класса MapBookChangeListener
. Наконец, метод помещает идентификатор, полученный из объекта HashMap
, в сессию приложения.
В дополнение к методу, который обрабатывает событие, вам нужен сам класс события. Этот класс очень прост в написании. Вы расширяете ActionEvent
и предоставляете конструктор, принимающий компонент, для которого событие находится в очереди, и метод, возвращающий компонент. Вот класс AreaSelectedEvent
, используемый с картой изображения:
public class AreaSelectedEvent extends ActionEvent {
public AreaSelectedEvent(MapComponent map) {
super(map);
}
public MapComponent getMapComponent() {
return ((MapComponent) getComponent());
}
}
Как объяснено в разделе Создание классов кастомного компонента, чтобы MapComponent
в первую очередь вызывал события, он должен реализовывать ActionSource
. Поскольку MapComponent
расширяет UICommand
, он также реализует ActionSource
.