Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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

425

import java.awt.*;

public class FilteringFiles extends JFrame { public FilteringFiles() {

super("FilteringFiles"); setDefaultCloseOperation(EXIT_ON_CLOSE);

//выводим окно на экран setSize(300, 200); setVisible(true);

//настраиваем компонент для выбора файла

JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Выберите текстовый файл");

//присоединяем фильтр chooser.addChoosableFileFilter(

new TextFilesFilter());

//выводим диалоговое окно на экран

int res = chooser.showOpenDialog(this); if ( res == JFileChooser.APPROVE_OPTION )

JOptionPane.showMessageDialog(

this, chooser.getSelectedFile());

}

// фильтр, отбирающий текстовые файлы class TextFilesFilter extends FileFilter {

// принимает файл или отказывает ему public boolean accept(java.io.File file) {

// все каталоги принимаем

if ( file.isDirectory() ) return true; // для файлов смотрим на расширение

return ( file.getName().endsWith(".txt") );

}

// возвращает описание фильтра public String getDescription() {

return "Текстовые файлы (*.txt)";

}

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new FilteringFiles(); } });

}

}

426

ГЛАВА 14

Мы создаем небольшое окно, и сразу же после того как это окно появляется на экране, выводим компонент для выбора файлов JFileChooser с подключенным к нему фильтром файлов. Настройка нам уже знакома: мы просто устанавливаем заголовок диалогового окна для открытия файлов, а затем выводим это окно на экран методом showOpenDialog().

Посмотрите, как создается фильтр файлов. Мы унаследовали внутренний класс от абстрактного класса FileFilter и переопределили два метода базового класса. Метод getDescription() не таит в себе никаких тайн и должен просто сообщать краткое описание фильтра файлов. Как правило, в это описание добавляется правило, по которому действует фильтр. В нашем случае мы просто указали маску, по которой отбираются файлы. Главная «рабочая лошадка» фильтра — метод accept(). Именно в нем нам необходимо проанализировать имя файла (или даже его содержимое) и сделать вывод о его пригодности для включения в список файлов, который окажется перед глазами пользователя. Обратите внимание, что в данный метод попадают абсолютно все файлы и каталоги, поэтому мы прежде всего проверяем, не каталог ли нам попался, и все каталоги включаем в список (в противном случае, при отсутствии в списке каталогов, пользователь просто не сможет перемещаться по файловой системе). Для обычных файлов мы проводим анализ имени: наш фильтр должен отбирать текстовые файлы, а их имена (точнее расширения) заканчиваются символами «.txt».

Присоединить фильтр файлов к компоненту JFileChooser можно двумя способами. Оба способа предназначены для присоединения нового фильтра к списку фильтров, уже имеющихся в компоненте JFileChooser. В примере мы применили первый способ, вызвав метод addChoosableFileFilter(). Данный метод присоединит наш фильтр файлов к списку остальных фильтров (а в компоненте JFileChooser всегда имеется, по крайней мере, один фильтр — тот, что пропускает все файлы и каталоги «без разбора»), но не выберет новый фильтр, так что пользователю самому придется его выбирать . Есть и второй способ — вызов метода setFileFilter(). Он, так же как и метод addChoosableFileFilter(), добавит фильтр в список имеющихся фильтров, но к тому же выберет его текущим фильтром и незамедлительно отфильтрует все файлы в текущей директории, так что пользователь сразу же увидит что позволяет выбирать данный фильтр. Какой метод использовать зависит от конкретной ситуации, главным образом от того, какой фильтр вы планируете использовать по умолчанию.

Запустив программу с примером, вы увидите, что после присоединения фильтра файлов компонент JFileChooser стал отображать только текстовые файлы (после того, как фильтр выбран в списке фильтров), и выбирать среди них нужный файл стало гораздо проще. Видно, как описание, переданное нами из метода getDescription(), появляется в раскрывающемся списке доступных фильтров файлов. Фильтры файлов намного облегчают жизнь пользователя, особенно при выборе из большого количества файлов, так что стоит всегда держать их «под рукой».

Список фильтров можно не только дополнять новыми участниками, но и уменьшать и узнавать, какие фильтры доступны в данный момент. Полезные методы для работы с фильтрами изложены в следующей таблице:

Таблица 14.7. Методы для работы с фильтрами файлов в компоненте JFileChooser

Метод

Описание

getChoosableFileFilters()

ВозвращаетмассиввсехдобавленныхвJFileChooser филь-

 

тров файлов, включая фильтр по умолчанию (для выбора

 

без ограничения)

getFileFilter()

Возращает фильтр, выбранный в данный момент. Полез-

 

ный метод, иногда именно выбранный фильтр определяет,

 

в каком формате будет сохранен файл

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

427

Таблица 14.7 (продолжение)

 

 

 

 

 

Метод

Описание

 

setAcceptAllFileFilterUsed(boolean)

Метод позволяет указать, надо ли показывать универсаль-

 

ный фильтр для выбора без ограничения. Отличная замена

 

ручному удалению этого фильтра

 

removeChoosableFileFilter(FileFilter)

Удаляет указанный в качестве параметра фильтр из списка

 

фильтров

 

Внешний вид файлов

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

Для описания внешнего вида файлов компонент JFileChooser применяет объект специального класса FileView из пакета javax.swing.filechooser. Данный объект служит для получения исчерпывающей информации о внешнем виде отображаемого файла7. С помощью объекта FileView вы можете задать имена файлов (если вам нужно, чтобы они отличались от имен файлов в файловой системе, например вы можете хранить название документа непосредственно в файле и вместо имени файла выводить на экран это название), значки для файлов и каталогов, описания типов файлов и многое другое. Для каждого атрибута внешнего вида файла предназначен свой метод, вы наследуете от класса FileView и переопределяете необходимые вам методы.

Рассмотрим теперь небольшой пример, в котором попробуем по-своему отобразить некоторые файлы и каталоги:

//CustomFileView.java

//Внешний вид файлов в компоненте JFileChooser import javax.swing.*;

import javax.swing.filechooser.*; import java.awt.*;

public class CustomFileView extends JFrame { public CustomFileView() {

super("CustomFileView"); setDefaultCloseOperation(EXIT_ON_CLOSE);

//выводим окно на экран setSize(300, 200); setVisible(true);

//настраиваем компонент для выбора файлов

JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Выберите файл");

7 Подобная ситуация типична для компонентов Swing и их внешнего вида: как правило, внешний вид определяется сторонними объектами. Это снова тот самый шаблон проектирования стратегия (strategy).

428

ГЛАВА 14

chooser.setFileView(new NewFileView( chooser.getFileSystemView()));

// показываем диалоговое окно

int res = chooser.showOpenDialog(this);

}

// объект, определяющий внешний вид файлов class NewFileView extends FileView {

// значки, применяемые для файлов

private Icon fileIcon = new ImageIcon("file.gif"); private Icon folderIcon = new ImageIcon("folder.gif");

//конструктору необходимо описание файловой системы public NewFileView(FileSystemView fileSystem) {

this.fileSystem = fileSystem;

}

private FileSystemView fileSystem;

//возвращает значок для файла

public Icon getIcon(java.io.File file) {

// основные части файловой системы пропускаем if ( fileSystem.isRoot(file) ||

fileSystem.isDrive(file) ) return null;

if ( file.isDirectory() ) return folderIcon;

else return fileIcon;

}

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new CustomFileView(); } });

}

}

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

Во внутреннем классе NewFileView, унаследованном от абстрактного класса FileView, мы описываем, как должны выглядеть файлы в нашем компоненте JFileChooser. В классе FileView имеется несколько методов, отвечающих в том числе за описание файла и его типа, однако мы ограничиваемся настройкой значков, которые будут соответствовать файлам, переопределяя только один метод getIcon(). В этом методе необходимо вернуть значок Icon. Мы будем возвращать собственные значки для всех файлов и каталогов. Правда, при работе с методами класса FileView надо иметь в виду следующее: в них передаются все отображаемые компонентом JFileChooser элементы, в том числе файлы, представляющие со-

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

429

бой корни файловой системы, устройства чтения гибких дисков и компакт-дисков, особые каталоги пользователя и т. п. Если для таких особых файлов возвращать те же значки, что применяются для обычных файлов и каталогов, пользователю станет неудобно работать с компонентом для выбора файлов и выглядеть такой компонент будет не лучшим образом. Именно поэтому мы передаем в конструктор внутреннего класса ссылку на используемое компонентом JFileChooser описание файловой системы FileSystemView. Вызывая методы объекта FileSystemView, мы узнаем, не принадлежит ли файл к «особенным», и для таких «особенных» файлов возвращаем вместо значка пустую (null) ссылку. Это означает, что значок для таких элементов подыщет текущий UI-представитель компонента JFileChooser. Обычные файлы и каталоги будут отображаться с нашими собственными значками.

Запустив программу с примером, вы увидите, как теперь выглядят каталоги и файлы в списке файлов компонента JFileChooser. Как правило, объект, отвечающий за внешний вид файлов, работает в тандеме с фильтром файлов определенного типа, так что пользователь сразу оценивает, какие файлы ему предстоит открывать и быстро запоминает их внешний вид. Как мы уже отметили, в классе FileView имеются и другие методы, которые позволят вам, к примеру, на свой лад описать файл или его тип (по умолчанию описания у файла либо вообще нет, либо используется описание файла, получаемое от операционной системы). Все они легко найдутся в интерактивной документации JDK.

Дополнительные компоненты

Несмотря на то, что компонент для выбора файлов JFileChooser чаще всего используется в своем стандартном виде, вы не ограничены тем, что вам предлагает библиотека, и можете добавить к стандартным компонентам, составляющим JFileChooser, свои собственные компоненты. Дополнительные компоненты, как правило, служат для предварительного просмотра содержимого файлов или для произведения над ними каких-либо действий без выхода из модального диалогового окна, в котором располагается JFileChooser. Специально для поддержки дополнительных компонентов в классе JFileChooser определен метод setAccessory(), который вы можете вызвать для добавления своего компонента (добавить, правда, можно только один компонент, но он может состоять из многих других компонентов). Куда будет добавлен ваш компонент, зависит от используемого внешнего вида, обычно он размещается рядом со списком файлов.

Как правило, при добавлении своих собственных компонентов вас начинает интересовать, что происходит в компоненте JFileChooser, например, какой именно файл в данный момент выбран пользователем. Это необходимо для совершения действий над файлом или его предварительного просмотра, даже если выбор пользователя не окончательный. Специального события, сообщающего о выборе очередного файла из списка, в классе JFileChooser нет, однако не стоит забывать о механизме привязанных свойств JavaBeans. Все наиболее важные свойства компонентов Swing являются привязанными, и узнать о любом их изменении вы сможете, присоединив к компоненту слушателя PropertyChangeListener. Компонент JFileChooser не является исключением: свойства, управляющие выделенным в данный момент файлом или каталогом, также относятся к привязанным, поэтому вы всегда будете знать, к какому файлу или каталогу перешел пользователь, и сможете произвести с этим файлом или каталогом необходимые действия.

А теперь добавим к стандартному компоненту для выбора файлов панель для предварительного просмотра (в нашем примере она будет поддерживать предварительный просмотр изображений). Мы будем следить за сменой выбранного файла (с помощью привязанного свойства) и, если выбранный файл будет хранить изображение, выводить на экран уменьшенный вариант этого изображения. К компоненту JFileChooser мы также присоединим фильтр файлов, который будет выбирать только файлы с изображениями — так просматривать и выбирать изображения будет еще удобнее.

Источник: https://studfile.net/preview/15935977/