420 |
ГЛАВА 14 |
окне взамен стандартного значка, поставляемого вместе с текущими внешним видом и поведением Swing.
Запустив программу с примером, вы воочию увидите, как стандартные диалоговые окна JOptionPane позволяют получать от пользователя подтверждение о проведении дальнейших действий, и сможете применять их в собственных программах, так что ваш пользователь не останется в неведении.
Дополнительные возможности
Чаще всего класс JOptionPane применяется так, как мы использовали его в рассмотренных примерах: вы вызываете один из многочисленных статических методов, выводящих на экран стандартное диалоговое окно, не забывая передать в метод список подходящих параметров, полностью определяющих внешний вид будущего окна. Но у класса JOptionPane имеются и другие достоинства. Прежде всего это способность работать в виде самого обыкновенного компонента: вы создаете объект класса JOptionPane, используя при этом подходящий конструктор, настраиваете остальные свойства с помощью методов get/set (а свойствами класса являются все свойства диалоговых окон, прежде задаваемых нами в виде параметров статических методов, в том числе тип сообщения, само сообщение, значок и т. п.), а затем выводите полученный компонент на экран так, как вам угодно (к примеру, в диалоговом окне, созданном своими руками, если вам это необходимо). Создание компонента имеет свои преимущества: вы получаете больший контроль над тем, где и когда появляются стандартные диалоговые окна, а также экономию памяти — стандартные диалоговые окна одного вида и предназначения могут создаваться один раз, меняться будут лишь текст сообщения и заголовок окна.
Далее можно использовать те методы showXXXDialog(), которые мы изучили в данной главе, а также методы с общим названием showInternalXXXDialog(). В последнем случае стандартные диалоговые окна появляются в специальном компоненте Swing с названием JDesktopPane, предназначенном для создания приложений с многодокументным интерфейсом (MDI). Но чтобы методы showInternalXXXDialog() работали, необходима поддержка в вашем приложении многодокументного интерфейса и рабочего стола (компонента JDesktopPane), а это, учитывая все снижающуюся популярность многодокументного интерфейса, встречается уже не так часто, к тому же в таком виде стандартные диалоговые окна привлекают к себе недостаточно внимания. Поэтому в подавляющем большинстве случаев вполне хватает изученных нами методов (и в большинстве случаев они лучше соответствуют нуждам приложений).
Помимо рассмотренных нами методов showXXXDialog(), предназначенных для вывода сообщений, ввода несложных данных и получения подтверждений, в классе JOptionPane имеется еще один метод с названием showOptionDialog(). С его помощью вы можете вывести на экран любое сообщение, разместить в нем любые компоненты и снабдить его нужными типом и набором альтернатив для выбора. Вот только метод этот довольно громоздкий, и, если вам потребуется совершенно особое диалоговое окно с необычным набором компонентов, лучше это диалоговое окно создать «с нуля», и заполнить компонентами окно JDialog.
Выбор файлов в компоненте JFileChooser
Выбор файлов необходим в любом более или менее приличном приложении: в самом деле, все, что пользователями делается, чаще всего сохраняется в файлах, даже если расположены они на удаленных серверах. Компонент JFileChooser — отличный и легко настраиваемый инструмент для выбора файлов и при необходимости каталогов. Особенности различных файловых систем скрыты в подклассах абстрактного
Стандартные диалоговые окна |
421 |
класса FileSystemView, и беспокоиться вам об |
этих различиях не придется: выбранный |
вами для приложения внешний вид отобразит файловую структуру как подобает -- соответственно текущей операционной системе5. В самом начале главы мы упомянули, что JFileChooser — это обычный компонент, унаследованный от класса JComponent, так что вы можете включить его в любое место своего интерфейса. Так оно и есть, но удобнее использовать пару методов, показывающих компонент для выбора файлов в собственном модальном диалоговом окне. Настроить и вывести на экран несложное диалоговое окно для открытия файла или сохранения в нем данных совсем легко. Рассмотрим пример:
//SimpleFileChooser.java
//Создание простых диалоговых окон
//открытия и сохранения файлов import javax.swing.*;
import java.awt.event.*; import java.awt.*;
public class SimpleFileChooser extends JFrame { // создадим общий экземпляр JFileChooser private JFileChooser fc = new JFileChooser(); public SimpleFileChooser() {
super("SimpleFileChooser"); setDefaultCloseOperation(EXIT_ON_CLOSE);
// кнопка, создающая диалоговое окно для открытия файла
JButton open = new JButton("Открыть..."); open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { fc.setDialogTitle("Выберите каталог");
//настроим для выбора каталога fc.setFileSelectionMode(
JFileChooser.DIRECTORIES_ONLY); int res = fc.showOpenDialog(
SimpleFileChooser.this);
//если файл выбран, покажем его
if ( res == JFileChooser.APPROVE_OPTION ) JOptionPane.showMessageDialog(
SimpleFileChooser.this,
fc.getSelectedFile());
}
});
5 Все операционные системы поддерживаются только одним стандартным внешним видом, поставляющимся вместе с JDK, — внешним видом Metal, который используется в Swing по умолчанию. Остальные внешние виды могут показывать только соответствующую файловую систему. Так что запускать под Windows программу с внешним видом CDE или Motif можно, но вот выбирать файлы в ней будет затруднительно — файловая система Unix для Windows не слишком подходит.
422 |
ГЛАВА 14 |
//кнопка, создающая диалоговое окно
//для сохранения файла
JButton save = new JButton("Сохранить..."); save.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { fc.setDialogTitle("Сохранение файла");
//настройка режима fc.setFileSelectionMode(
JFileChooser.FILES_ONLY); int res = fc.showSaveDialog( SimpleFileChooser.this);
//сообщим об успехе
if ( res == JFileChooser.APPROVE_OPTION ) JOptionPane.showMessageDialog(
SimpleFileChooser.this, "Файл сохранен");
}
}); // добавим кнопки и выведем окно на экран
setLayout(new FlowLayout()); add(open);
add(save); setSize(300, 200); setVisible(true);
}
public static void main(String[] args) { SwingUtilities.invokeLater(
new Runnable() {
public void run() { new SimpleFileChooser(); } });
}
}
В примере мы создаем небольшое окно с двумя кнопками. После щелчков на этих кнопках на экране появляются диалоговые окна для открытия и сохранения файлов. Заметьте, что на весь пример у нас всего один экземпляр компонента для выбора файлов JFileChooser, хотя мы и сохраняем файлы, и открываем их. Более того, эти действия можно совершать многократно, поскольку, как уже отмечалось, JFileChooser представляет собой обычный компонент, и вы можете создать его один раз, а затем после соответствующей настройки снова и снова выводить в подходящих диалоговых окнах. При щелчке на первой кнопке на экран выводится диалоговое окно открытия файлов. Посмотрите, как можно задать соответствующий заголовок для диалогового окна методом setDialogTitle(). Перед выводом диалогового окна для выбора файлов на экран мы настраиваем режим выбора. Компонент JFileChooser может работать в одном из трех режимов (режим выбора хранится в свойстве fileSelectionMode), перечисленных в табл. 14.5.
Стандартные диалоговые окна |
423 |
|
Таблица 14.5. Доступные режимы работы JFileChooser |
|
|
|
|
|
Режим работы |
Описание |
|
FILES_ONLY |
Пользователю длявыбора(независимооттого, сохраняетсяфайлили |
|
|
открывается) будут доступны только файлы, но не каталоги. По умол- |
|
|
чанию JFileChooser работает именно в этом режиме и правильно де- |
|
|
лает, поскольку подобный режим необходим чаще остальных. Именно |
|
|
в этом режиме пользователь сохраняет свою работу в файлах |
|
FILES_AND_DIRECTORIES |
В этом режиме пользователь может выбирать и каталоги, и файлы. |
|
|
Как правило, этот режим хорош там, где вы меняете общие свойства |
|
|
файловой системы, и файлы для вас не отличаются от каталогов |
|
DIRECTORIES_ONLY |
Этотвесьмаценныйрежимразрешаетпользователювыбиратьисключи- |
|
|
тельно каталоги. Особенно хорош он там, где нужно выбирать каталоги |
|
|
под временные файлы, указывать каталоги с исходными текстами и т. п. |
|
Мы выбираем последний режим, так что открыть вы сможете только каталог. Для вывода диалогового окна открытия файлов (в нашем случае каталогов) служит удобный метод showOpenDialog(). Этому методу нужно только передать ссылку на «родительский» компонент, относительно которого окно будет располагаться на экране. В ответ метод возвращает целое число, определяющее сделанный пользователем выбор (табл. 14.6).
Таблица 14.6. Значения, возвращаемые методами класса JFileChooser
Константа |
Описание |
APPROVE_OPTION |
Выбор файла в диалоговом окне прошел успешно, можно получить |
|
выбранный файл методом getFile() |
CANCEL_OPTION |
Пользователь отменил выбор файла, щелкнув на кнопке Cancel |
ERROR_OPTION |
При выборе файла произошла ошибка, или пользователь закрыл диа- |
|
логовое окно для выбора файлов |
В нашем примере мы проверяем, успешен ли был выбор файла, и если да (метод showOpenDialog() вернул нам значение APPROVE_OPTION), выводим на экран имя выбранного каталога (с помощью класса JOptionPane).
424 |
ГЛАВА 14 |
Щелкнув на второй кнопке, вы сможете вызвать на экран диалоговое окно для сохранения файлов. Разница между ним и создаваемым первой кнопкой окном для открытия файлов невелика, всего лишь в надписях, используемых для компонентов JFileChooser. Мы также устанавливаем режим выбора файлов (FILES_ONLY), задаем собственный заголовок для создаваемого окна методом setDialogTitle() и выводим диалоговое окно на экран методом showSaveDialog(). Так же как и в случае окна для открытия файлов, для этого требуется только один параметр — «родительский» компонент. Если выбор файла для сохранения проходит успешно (нам возвращают значение APPROVE_ OPTION), на экране появляется краткое сообщение, подтверждающее успешное сохранение файла (которое, правда, беззастенчиво лукавит, поскольку никакого сохранения не происходит).
Запустив программу с примером, вы сможете выбрать любой файл в своей файловой системе с помощью компонента JFileChooser. Для этого, как нетрудно видеть, нужно всего несколько строк кода. Но не забывайте, что компонент JFileChooser предназначен всего лишь для выбора файла, а проводить с выбранным файлом соответствующие манипуляции (записывать в него информацию или анализировать его содержимое) вам придется своими руками.
Вопрос с переводом англоязычных строк в приложении, использующим компонент JFileChooser, не отличается от подхода в компоненте JOptionPane. По умолчанию все строки написаны на английском языке (что легко видеть на снимке экрана), они берутся они из специальных ресурсов класса UIManager. Например, заменить надпись Open можно так: UIManager.put(«FileChooser.openButtonText», «Открыть»). Заменив эти ресурсы на строки, написанные на нужном вам языке, вы сможете перевести стандартные диалоги (но заменять строки необходимо перед созданием компонентов). Ну а полный список ключей для этих строк размещен в интерактивной документации JDK и Swing.
Фильтры файлов
По умолчанию в списке файлов, который компонент JFileChooser предоставляет пользователю, содержатся все файлы из текущего каталога (того, что пользователь просматривает в данный момент). Порой это очень неудобно: как правило, пользователю необходим файл с определенным именем или типом, и ему приходится «рыскать» по всему списку в поиске нужного (только представьте себе поиск нужного файла среди нескольких тысяч). Мы можем сократить круг поиска пользователя с помощью фильтра файлов, который легко встраивается в компонент JFileChooser.
Фильтры файлов для JFileChooser описаны абстрактным классом FileFilter из пакета javax.swing.filechooser. Дело происходит следующим образом: вы наследуете от класса FileFilter, основным методом которого является accept(). Этот метод класс JFileChooser вызывает для каждого файла, перед тем, как добавить его в список файлов, предоставляемых для выбора пользователю. Вы, в методе accept(), анализируете файл (как правило, по имени, хотя никто не запрещает вам анализировать файл по его содержимому, если вы захотите удостовериться, что оно соответствует определенному формату) и решаете, «достоин» ли файл появления перед глазами пользователя6. Рассмотрим несложный пример, в котором попробуем написать собственный фильтр файлов:
//FilteringFiles.java
//Фильтры файлов в компоненте JFileChooser import javax.swing.*;
import javax.swing.filechooser.*;
6 Это не что иное, как шаблон проектирования стратегия (strategy)., один из самых распространенных в Swing.