Программирование на Java
Шрифт:
MouseListener и MouseEvent
Этот слушатель имеет методы mouseEntered и mouseExited. Первый вызывается, когда курсор мыши появляется над компонентом, а второй – когда выходит из его границ.
Для обработки нажатий кнопки мыши служат три метода: mousePressed, mouseReleased и mouseClicked. Если пользователь нажал, а затем отпустил кнопку, то слушатель получит все три события в указанном порядке. Если щелчков было несколько, то метод getClickCount класса MouseEvent вернет количество. Как уже указывалось, методы getX и getY возвращают координаты точки, где произошло событие. Чтобы определить, какая кнопка мыши была нажата, нужно воспользоваться
(event.getModifiers &
MouseEvent.BUTTON1_MASK)!=0
Как правило, первая кнопка соответствует левой кнопке мыши.
KeyListener и KeyEvent
Этот слушатель отслеживает нажатие клавиш клавиатуры и имеет три метода: keyTyped, keyPressed, keyReleased. Первый отвечает за ввод очередного Unicode -символа с клавиатуры. Метод keyPressed сигнализирует о нажатии, а keyReleased – об отпускании некоторой клавиши. Взаимосвязь между этими событиями может быть нетривиальной. Например, если пользователь нажмет и будет удерживать клавишу Shift и в это время нажмет клавишу "A", произойдет одно событие типа keyTyped и несколько keyPressed/Released. Если пользователь нажмет и будет удерживать, например, пробел, то после первого keyPressed будет многократно вызван метод keyTyped, а после отпускания – keyReleased.
В классе KeyEvent определено множество констант, которые позволяют точно идентифицировать, какая клавиша была нажата и в каком состоянии находились служебные клавиши ( Ctrl, Alt, Shift и так далее).
FocusListener и FocusEvent
В каждом приложении один из компонентов обладает фокусом и может получать события от клавиатуры. Фокус можно переместить, например, щелкнув мышкой по другому компоненту, либо нажав клавишу Tab.
Интерфейс FocusListener содержит два метода – focusGained и focusLost (получен/потерян).
TextListener и TextEvent
Компоненты-наследники TextComponent отвечают за ввод текста и порождают TextEvent. Слушатель имеет один метод textValueChanged. С его помощью можно отслеживать каждое изменение текста, чтобы, например, выдавать пользователю подсказку, основываясь на первых введенных символах.
ItemListener и ItemEvent
Это событие могут генерировать такие классы, как Checkbox, Choice, List. Слушатель имеет один метод itemStateChanged, который сигнализирует об изменении состояния элементов.
AdjustmentListener и AdjustmentEvent
Это событие генерируется компонентом ScrollBar. Слушатель имеет один метод adjustmentValueChanged, сигнализирующий об изменении состояния полосы прокрутки.
WindowListener и WindowEvent
Это событие сигнализирует об изменении состояния окна (класс Window и его наследники).
Рассмотрим особо один из методов слушателя – windowClosing. Этот метод вызывается, когда пользователь предпринимает попытку закрыть окно, например, нажимая на соответствующую кнопку в заголовке окна. Мы видели из примеров ранее, что в Java окна при этом не закрываются. Дело в том, что AWT лишь посылает WindowEvent в ответ на такое действие, а инициировать закрытие окна должен программист:
public class WindowClosingAdapter
extends WindowAdapter {
public void windowClosing(WindowEvent e)
{
((Window)e.getSource).dispose;
}
}
Объявленный
Когда окно будет закрыто, у слушателя вызывается еще один метод – windowClosed.
ComponentListener и ComponentEvent
Это событие отражает изменение основных параметров компонента – положение, размер, свойство visible.
ContainerListener и ContainerEvent
Это событие позволяет отслеживать изменение списка содержащихся в этом контейнере компонент.
С развитием Java в AWT появляются и другие события, например, позволяющие поддерживать колесико мыши. Однако все они работают по точно такой же схеме, а потому их можно легко освоить самостоятельно.
Обработка событий с помощью внутренних классов
Еще в лекции, посвященной объявлению классов, было указано, что в теле класса можно объявлять внутренние классы. До сих пор такая возможность не была востребована в наших примерах, однако обработка событий AWT – как раз удобный случай рассмотреть такие классы на примере анонимных классов.
Предположим, в приложение добавляется кнопка, которой следует добавить слушателя. Зачастую бывает удобно описать логику действий в отдельном методе того же класса. Если вводить слушателя, как делалось раньше – в отдельном классе, то это сразу порождает ряд неудобств: появляется новый, малосодержательный класс, которому к тому же необходимо передать ссылку на исходный класс и так далее.
Гораздо удобнее поступить следующим образом:
Button b = new Button;
b.addActionListener(new ActionListener
{
public void actionPerformed(ActionEvent e) {
processButton;
}
}
);
Рассмотрим подробно, что происходит в этом примере. Сначала создается кнопка, у которой затем вызывается метод addActionListener. Обратим внимание на аргумент этого метода. Может сложится впечатление, что производится попытка создать экземпляр интерфейса ( new ActionListener ), однако это невозможно. Дело меняет фигурная скобка, которая указывает, что порождается экземпляр нового класса, объявление которого последует за этой скобкой. Класс наследуется от Object и реализует интерфейс ActionListener. Ему необходимо реализовать метод actionPerformed, что и делается. Обратите внимание на еще одну важную деталь – в этом методе вызывается processButton. Это метод, который мы планировали разместить во внешнем классе. Таким образом, внутренний класс может напрямую обращаться к методам внешнего класса.
Такой класс называется анонимным, он не имеет своего имени. Однако правило, согласно которому компилятор всегда создает .class -файл для каждого класса Java, действует и здесь. Если внешний класс называется Test, то после компиляции появится файл Test$1.class.
Пример приложения, использующего модель событий
В заключение темы, посвященной событиям, рассмотрим пример приложения, которое активно их использует.
Попробуем написать примитивный графический редактор, который позволяет рисовать с помощью курсора – если перемещать его с нажатой кнопкой мыши, то будет появляться линия. Нажатие пробела очищает поле.