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