Интерфейс Action (действие) и класс AbstractAction

Очень часто одна и та же команда дублируется в графическом интерфейсе в нескольких местах. Например, команда «Копировать» может присутствовать в главном меню окна, в контекстном меню некоторого объекта, а также в виде кнопки на инструментальной панели. Это необходимо для удобства пользования программой. Однако, привязывать ко всем этим объектам (кнопкам и командам меню) одинаковых слушателей довольно утомительно. Более того, все эти команды одинаково должны реагировать на изменения состояния программы: если копирование по каким-то причинам становится невозможным, то все элементы управления, представляющие данную команду, должны сделаться неактивными.

Для упрощения работы в таких ситуациях предусмотрен интерфейс Action. Он собирает в одном месте все, что относится к некоторому действию: обработчик, показатель активности, всплывающую подсказку, значок и т.д.

Интерфейс Action унаследован от интерфейса ActionListener, поэтому его главный метод — actionPerformed(ActionEventevent). Именно здесь программируется само действие. Но помимо этого посредством метода putValue(Stringkey, Objectvalue) можно задать одно из дополнительных свойств действия. Первый параметр — строковый идентификатор свойства. Он может принимать одно из значений, описанных в константах интерфейса Action. Второй параметр — объект, представляющий собой значение свойства.

Основные свойства интерфейса Action (точнее, соответствующие им константы):

NAME — имя действия,

SMALL_ICON — значок, соответствующий действию,

SHORT_DESCRIPTION — краткое описание действия (для всплывающей подсказки).

Метод setEnabled(booleanenabled) позволяет сделать действие активным или неактивным.

На основе созданного действия можно создавать некоторые элементы управления, передавая это действие в качестве единственного параметра конструктора. К таким элементам управления, в частности, относятся элементы меню и кнопки.

Недостаток интерфейса 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, а затем внимательно проанализируйте его.

Стандартные диалоговые окна

Класс JOptionPane

Неотъемлемой частью большинства программ являются небольшие диалоговые окна: для вывода пользователю сообщения (например, сообщения об ошибке), для вопроса, ответ на который важен для выполнения текущего действия (например, просьба подтвердить или отменить запрашиваемую операцию). Эти диалоги могут быть запрограммированы вручную на основе класса JFrame. Однако ввиду того, что они являются типичными для многих программ, Swing предоставляет в распоряжение программиста несколько готовых классов для работы с ними.

Чаще всего используется класс JOptionPane, содержащий несколько статических методов, отображающих стандартные диалоги.

Метод showMessageDialog() выводит на экран диалоговое окно, информирующее пользователя. Оно содержит надпись, значок и кнопку ОК. Существует несколько разновидностей этого метода с разными наборами параметров. Самый простой из них showMessageDialog(Componentcomponent, Objectcontent) требует указания компонента, над которым должно появиться диалоговое окно и содержимого окна. Чаще всего содержимым окна является некоторая строка, а вместо первого параметра передается null — тогда окно появляется по центру экрана. Более «продвинутый» вариант showMessageDialog(Componentcomponent, Objectcontent, Stringtitle, inttype) позволяет задать также свой заголовок окна и выбрать его тип (влияет на иконку в окне): сообщение об ошибке (ERROR_MESSAGE), предупреждение (WARNING_MESSAGE), информация (INFORMATION_MESSAGE).

Диалоговое окно является модальным. Это значит, что пока пользователь не нажмет в этом окне кнопку OK, программа окажется заблокирована — пользователь не сможет работать с другими окнами.

Пронаблюдаем действие метода на простом примере:

public class SimpleWindow extends JFrame { private JButton button; SimpleWindow(){ super ("Предупреждающийдиалог");setDefaultCloseOperation(EXIT_ON_CLOSE);button = new JButton("Информация");button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) {JOptionPane.showMessageDialog(button, "Ненадобылонажиматьнаэтукнопку", "Информация", JOptionPane.WARNING_MESSAGE);} });getContentPane().setLayout(new FlowLayout());getContentPane().add(button);setSize(200,150);}}

Кнопка button сделана полем класса окна, чтобы можно было получить к ней доступ из анонимного класса-слушателя.

Другое часто используемое диалоговое окно — окно вопроса. В этом окне несколько кнопок, одну из которых пользователь должен нажать. В программу, вызывающую это диалоговое окно, возвращается информация о выборе пользователя, на основе которой и строится дальнейший ход работы программы.

Данноеокноотображаетсяметодом showConfirmDialog(Component component, Object content). Параметры этого метода идентичны по смыслу параметрам showMessageDialog(), но в диалоговом окне появится не одна кнопка, а три: «Yes», «No» и «Cancel». Более того, метод возвращает значение, которое можно сравнить с константами YES_OPTION, NO_OPTION и CANCEL_OPTION. Логику работы с этим методом проиллюстрирует пример:

public class SimpleWindow extends JFrame { JButton button; SimpleWindow(){ super ("Предупреждающийдиалог");setDefaultCloseOperation(EXIT_ON_CLOSE);button = new JButton("Выход");button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (JOptionPane.showConfirmDialog(button, "Выуверены, чтохотитевыйти?") == JOptionPane.YES_OPTION) System.exit(0);} });getContentPane().setLayout(new FlowLayout());getContentPane().add(button);setSize(200,150);}}

Метод имеет еще четыре разновидности с разным набором параметров, позволяющих изменять заголовок и значок окна, а также набор кнопок.

Класс JFileChooser

Swing содержит готовое окно для выбора файла (полезное, например, для программирования пункта меню Файл -->Открыть). Объект класса JFileChooser создается простым конструктором без параметров, после чего может выводиться на экран методом showOpenDialog(). Этот метод возвращает результат действий пользователя по выбору файла, который сравнивается с одной из следующих констант:

APPROVE_OPTION — выбор файла прошел успешно. Теперь можно методом getFile() получить выбранный файл.

CANCEL_OPTION — пользователь отменил выбор файла, щелкнув на кнопке Cancel.

ERROR_OPTION — при выборе файла произошла ошибка, либо пользователь закрыл диалоговое окно крестиком.

Метод showSaveDialog() отображает то же самое окно, но теперь оно работает в режиме сохранения. Пользователь выбирает директорию для сохранения файла и может ввести его имя. Метод возвращает результат того же типа, что и showOpenDialog(). Если выбор пути для сохранения прошел успешно, вызов метода getFile() вернут путь, куда пользователь желает сохранить файл.

Следует иметь в виду, что сам класс JFileChooser ничего не открывает и не сохраняет. Он только возвращает путь к выбранному пользователем файлу. А открыть его или сохранить файл в заданном месте должна уже сама программа.

Метод setDialogTitle(Stringtitle) позволяет задать окну заголовок.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: