Интерфейс Action (действие) и класс AbstractAction
Очень часто одна и та же команда дублируется в графическом интерфейсе в нескольких местах. Например, команда «Копировать» может присутствовать в главном меню окна, в контекстном меню некоторого объекта, а также в виде кнопки на инструментальной панели. Это необходимо для удобства пользования программой. Однако, привязывать ко всем этим объектам (кнопкам и командам меню) одинаковых слушателей довольно утомительно. Более того, все эти команды одинаково должны реагировать на изменения состояния программы: если копирование по каким-то причинам становится невозможным, то все элементы управления, представляющие данную команду, должны сделаться неактивными.
Для упрощения работы в таких ситуациях предусмотрен интерфейс Action. Он собирает в одном месте все, что относится к некоторому действию: обработчик, показатель активности, всплывающую подсказку, значок и т.д.
Интерфейс Action унаследован от интерфейса ActionListener, поэтому его главный метод – actionPerformed(ActionEvent event). Именно здесь программируется само действие. Но помимо этого посредством метода putValue(String key, Object value) можно задать одно из дополнительных свойств действия. Первый параметр – строковый идентификатор свойства. Он может принимать одно из значений, описанных в константах интерфейса Action. Второй параметр – объект, представляющий собой значение свойства.
Основные свойства интерфейса Action (точнее, соответствующие им константы):
NAME – имя действия,
SMALL_ICON – значок, соответствующий действию,
SHORT_DESCRIPTION – краткое описание действия (для всплывающей подсказки).
Метод setEnabled(boolean enabled) позволяет сделать действие активным или неактивным.
На основе созданного действия можно создавать некоторые элементы управления, передавая это действие в качестве единственного параметра конструктора. К таким элементам управления, в частности, относятся элементы меню и кнопки.
Недостаток интерфейса Action – в нем слишком много вспомогательных абстрактных методов (их семь, в том числе setEnabled() и putValue()) и программировать их достаточно утомительно. Поэтому обычно используется реализующий данный интерфейс класс AbstractAction, в котором «не заполнен» единственный метод –actionPerformed(), а его все равно необходимо определить для программирования сути действия.
Пример.
public class SimpleWindow extends JFrame {
private ExitAction exitAction;
SimpleWindow(){
super("Окно с меню");
setDefaultCloseOperation(EXIT_ON_CLOSE);
exitAction = new ExitAction();
DeactivateAction deactivateAction = new DeactivateAction();
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("Файл");
fileMenu.add(new JMenuItem("Новый"));
fileMenu.addSeparator();
fileMenu.add(deactivateAction);
fileMenu.add(exitAction);
menuBar.add(fileMenu);
setJMenuBar(menuBar);
JToolBar toolBar = new JToolBar("Панель инструментов");
toolBar.add(exitAction);
toolBar.add(deactivateAction);
getContentPane().add(toolBar, BorderLayout.NORTH);
JPanel panel = new JPanel();
panel.add(new JButton(exitAction));
panel.add(new JButton(deactivateAction));
getContentPane().add(panel);
setSize(250,250);
}
class ExitAction extends AbstractAction {
ExitAction(){
putValue(Action.NAME, "Выйти");
putValue(Action.SHORT_DESCRIPTION, "Программа перестанет работать, а окно исчезнет с экрана.");
putValue(Action.SMALL_ICON, new ImageIcon("2.gif"));
}
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
}
class DeactivateAction extends AbstractAction {
DeactivateAction(){
putValue(Action.NAME, "Запретить выход");
putValue(Action.SMALL_ICON, new ImageIcon("1.gif"));
}
public void actionPerformed(ActionEvent event) {
if (exitAction.isEnabled()){
exitAction.setEnabled(false);
putValue(Action.NAME, "Разрешить выход");
}else{
exitAction.setEnabled(true);
putValue(Action.NAME, "Запретить выход");
}
}
}
}
В примере в окне описаны два внутренних класса-действия, одно из которых – это выход из программы. Объект этого класса, exitAction, является внутренним полем класса-окна и на его основе создается пункт меню и две кнопки. Второй класс-действие активирует и деактивирует объект exitAction (при этом изменяется соответствующий действию текст). Запустите пример и пронаблюдайте за тем, как выглядят и ведут себя объекты на основе Action, а затем внимательно проанализируйте его.
Дата добавления: 2017-01-26; просмотров: 1809;