Несколько слушателей одного источника
В начале этой главы, в листингах 12.1-12.3, мы привели пример класса TextMove, слушающего сразу два компонента: поле ввода tf типа TextFieid и кнопку b типа Button.
Чаще встречается обратная ситуация – несколько слушателей следят за одним компонентом. В том же примере кнопка ь в ответ на щелчок по ней кнопки мыши совершала еще и собственные действия – она "вдавливалась", а при отпускании кнопки мыши становилась "выпуклой". В классе Button эти действия выполняет peer-объект.
В классе FiowerButton листинга 10.6 такие же действия выполняет метод paint() этого класса.
В данной модели реализован design pattern под названием observer.
К каждому компоненту можно присоединить сколько угодно слушателей одного и того же события или разных типов событий. Однако при этом не гарантируется какой-либо определенный порядок их вызова, хотя чаще всего слушатели вызываются в порядке написания методов addXxxListener ().
Если нужно задать определенный порядок вызовов слушателей для обработки события, то придется обращаться к ним друг из друга или создавать объект, вызывающий слушателей в нужном порядке.
Ссылки на присоединенные методами addxxxbistener () слушатели можно было бы хранить в любом классе-коллекции, например, vector, но в пакет j ava .awt специально для этого введен класс AWTEventMuiticaster. Он реализует все одиннадцать интерфейсов xxxListener, значит, сам является слушателем любого события. Основу класса составляют своеобразные статические методы addo, написанные для каждого типа событий, например:
add(ActionListener a, ActionListener b)
Своеобразие этих методов двоякое: они возвращают ссылку на тот же интерфейс, в данном случае, ActionListener, и присоединяют объект а к объекту ь, создавая совокупность слушателей одного и того же типа. Это позволяет использовать их наподобие операций а += b. Заглянув в исходный текст класса Button, вы увидите, что метод addActionListener () очень прост:
public synchronized void addActionListener(ActionListener 1){ if (1 = null){ return; } actionListener = AWTEventMuiticaster.add(actionListener, 1); newEventsOnly = true; }
Он добавляет к совокупности слушателей actionListener нового слушателя 1.
Для событий типа inputEvent, а именно, KeyEvent и MouseEvent, есть возможность прекратить дальнейшую обработку события методом consume (). Если записать вызов этого метода в класс-слушатель, то ни peer-объекты, ни следующие слушатели не будут обрабатывать событие. Этим способом обычно пользуются, чтобы отменить стандартные действия компонента, например, "вдавливание" кнопки.