Механизм обработки событий библиотеки Swing
В контексте графического интерфейса пользователя наблюдаемыми объектами являются элементы управления: кнопки, флажки, меню и т.д. Они могут сообщить своим наблюдателям об определенных событиях, как элементарных (наведение мышкой, нажатие клавиши на клавиатуре), так и о высокоуровневых (изменение текста в текстовом поле, выбор нового элемента в выпадающем списке и т.д.).
Наблюдателями должны являться объекты классов, поддерживающих специальные методы, о которых «знает» наблюдаемый и вызывает их при наступлении события. Такие классы в терминологии Swing называются слушателями.
Универсальный слушатель ActionListener
Среди многочисленных событий, на которые реагирует каждый элемент управления (и о которых он оповещает соответствующих слушателей, если они к нему присоединены), есть одно основное, вытекающее из самой сути компонента и обрабатываемое значительно чаще, чем другие. Например, для кнопки это щелчок на ней, а для выпадающего списка — выбор нового элемента.
Для отслеживания и обработки такого события может быть использован особый слушатель ActionListener, имеющий один метод:
public void actionPerformed(ActionEvent event).
У использования ActionListener есть небольшое преимущество. Кроме того очень удобно запомнить и постоянно использовать один класс с одним методам и обращаться к остальным лишь в тех относительно редких случаях, когда возникнет такая необходимость.
Обработка нажатия кнопки
Разработчику необходимо навесить на JButton слушателя, который будет выполняться, как только пользователь нажмет на кнопку.
Как только пользователь нажимает кнопку, создается событие ActionEvent, которое передается слушателям кнопки. Для того, чтобы организовать слушателя, Swing предоставляет интерфейс ActionListener, который необходимо реализовать. Интерфейс ActionListener требует только реализации одного метода — actionPerformed. Пример класса, реализующего интерфейс ActionListener представлен ниже.
public class TestActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//Код, который нужно выполнить при нажатии
}}
После того, как обработчик создан, его необходимо добавить к кнопке. Делается это при помощи метода addActionListener. В качестве параметра методу передается обработчик. Например, это можно сделать вот так:
JButton button = new JButton("Test button");
ActionListener actionListener = new TestActionListener();
button.addActionListener(actionListener);
Здесь мы создаем сначала кнопку. Потом создаем экземпляр нашего слушателя TestActionListener, а затем добавляем его в качестве слушателя к кнопке с помощью вызова addActionListener и передаем ему экземпляр обработчика. Вообще слушателей может быть неопределенное количество. Если нам будет необходимо два или более слушателей, которые должны будут по-разному реагировать на нажатие кнопки, то для каждого из них вызовем addActionListener.
Работа с меню в библиотеке Swing
Неотъемлемой частью современных оконных программ является меню, представляющее собой удобно сгруппированный набор команд. Оно располагается вдоль верхней границы окна и содержит команды, относящиеся ко всему приложению (точнее, все команды, которые можно выполнить, работая с данным окном).
Создание меню
Меню окна представлено в Swing классом JMenuBar. По сути своей этот класс представляет собой панель с менеджером расположения BoxLayout (по горизонтали), в которую можно добавлять не только элементы меню, но и что угодно: хоть выпадающие списки, хоть панели с закладками. Однако для удобства пользования программой предпочтительнее использовать «традиционные» возможности меню.
Главное меню должно быть присоединено к окну методом setJMenuBar(JMenuBar menuBar).
Элементами главного меню являются пункты меню верхнего уровня — выпадающие прямоугольные блоки команд — объекты класса JMenu. Конструктор JMenu(String title) принимает один параметр: название пункта меню, которое будет отображаться в строке главного меню.
Пункты меню верхнего уровня, в свою очередь, состоит из пунктов меню, представленных классом JMenuItem. По логике работы пункты меню аналогичны кнопке JButton, то есть при нажатии на него пользователем выполняется какое-то действие.
Создать элемент меню можно пустым конструктором JMenuItem либо (что более востребовано) одним из конструкторов, в которые передается текст и/или значок элемента меню: JMenuItem(String text), JMenuItem(Icon icon), JMenuItem(String text, Icon icon). Конечно, в любой момент текст и значок можно сменить методами setText(String text) и setIcon(Icon icon) соответственно.
Элемент добавляется в меню методом add(JMenuItem item) класса JMenu. Чтобы отделить группы взаимосвязанных элементов меню, можно добавить между ними разделитель методом addSeparator() класса JMenu.
Кроме того, в меню можно добавить и другое меню. В этом случае образуется последовательность вложенных друг в друга подменю, что довольно часто встречается в современных программах. Но не следует увлекаться: глубина вложенности более трех уровней скорее всего приведет к неудобствам пользования программой.
Создадим главное меню окна, состоящее из двух подменю: «Файл» и «Правка», причем в меню «Правка» поместим выпадающее подменю. Кроме того, воспользуемся знаниями о менеджере расположения главного меню, чтобы добавить с правого края значок (наподобие того, как это сделано в браузере Internet Explorer).
SimpleWindow(){
super("Окно с меню");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("Файл");
fileMenu.add(new JMenuItem("Новый"));
fileMenu.add(new JMenuItem("Открыть", new ImageIcon("1.gif")));
fileMenu.add(new JMenuItem("Сохранить"));
fileMenu.addSeparator();
fileMenu.add(new JMenuItem("Выйти"));
JMenu editMenu = new JMenu("Правка");
editMenu.add(new JMenuItem("Копировать"));
JMenu pasteMenu = new JMenu("Вставить");
pasteMenu.add(new JMenuItem("Из буфера"));
pasteMenu.add(new JMenuItem("Из файла"));
editMenu.add(pasteMenu);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(Box.createHorizontalGlue());
menuBar.add(new JLabel(new ImageIcon("2.gif")));
setJMenuBar(menuBar);
setSize(250,150);
}
Обработка команд меню
Как было сказано, каждый элемент меню по сути представляет собой кнопку, поэтому реагирует на те же события и позволяет присоединять к себе тех же слушателей, что и кнопка. Поэтому можно назначить реакцию на команды меню точно так же, как делалось для кнопки. Например, чтобы при выборе в меню элемента «Выйти» программа прекращала свою работу, следует заменить в примере команду
fileMenu.add(new JMenuItem("Выйти"));
на последовательность команд:
JMenuItem exit = new JMenuItem("Выйти");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);}});
fileMenu.add(exit);
Командой System.exit(0) прекращается работа текущего приложения.