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

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

430

ГЛАВА 14

//PreviewingFiles.java

//Предварительный просмотр файлов

//в компоненте JFileChooser import javax.swing.*;

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

import java.awt.*;

public class PreviewingFiles extends JFrame { public PreviewingFiles() {

super("PreviewingFiles"); setDefaultCloseOperation(EXIT_ON_CLOSE);

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

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

JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Выберите изображение");

//присоединяем фильтр chooser.setFileFilter(new ImageFilesFilter());

//убираем универсальный фильтр chooser.setAcceptAllFileFilterUsed(false);

//присоединяем дополнительный компонент

Previewer previewer = new Previewer(); chooser.setAccessory(previewer);

//регистрируем в качестве слушателя chooser.addPropertyChangeListener(previewer);

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

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

JOptionPane.showMessageDialog(

this, chooser.getSelectedFile());

}

// компонент для предварительного просмотра class Previewer extends JPanel

implements PropertyChangeListener { private JLabel label;

public Previewer() {

//настраиваем контейнер setLayout(new BorderLayout());

setPreferredSize(new Dimension(200, 200));

//создаем надпись в панели прокрутки

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

431

label = new JLabel();

JScrollPane scroller = new JScrollPane(label); add(scroller);

}

public void propertyChange(PropertyChangeEvent e) { if ( e.getPropertyName().equals(

JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) { // сменился выбранный файл, покажем его

if ( e.getNewValue() != null ) label.setIcon(new ImageIcon(

e.getNewValue().toString()));

}

}

}

// фильтр, отбирающий файлы с изображениями class ImageFilesFilter extends FileFilter {

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

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

if ( file.isDirectory() ) return true;

//имя файла не будет учитывать регистр

String name = file.getName().toLowerCase();

//для файлов смотрим на расширение return ( name.endsWith(".jpg") ||

name.endsWith(".gif") || name.endsWith(".png") );

}

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

return "Изображения (*.jpg, *.gif, *.png)";

}

}

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

new Runnable() {

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

}

}

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

432

ГЛАВА 14

ния (отбор производится на основе расширения файла). Так как изображения некоторые программы и аппаратные устройства именуют по-разному, имеет смысл проверять окончание файлов вне зависимости от регистра. Для этого мы делаем имя файла строчным. Чтобы пользователь не смог выбрать фильтр без ограничений, мы отключаем его методом setAcceptAllFileFilterUsed(false). Напоследок производится настройка компонента для предварительного просмотра изображений Previewer: после создания мы присоединяем его к компоненту для выбора файлов, применяя метод setAccessory(). Прежде чем вывести компонент JFileChooser на экран, мы регистрируем в нем слушателя событий PropertyChangeEvent, которые запускаются при смене значений привязанных свойств. Для удобства слушатель реализован все в том же классе Previewer.

Компонент, реализующий предварительный просмотр изображений, описан во внутреннем классе Previewer и унаследован от панели JPanel. Состоит он из панели прокрутки, добавленной в центр компонента (в компоненте задействуется менеджер расположения BorderLayout), в панели прокрутки располагается надпись JLabel, которая и будет использоваться для вывода изображения. Заметьте, что мы вручную указываем предпочтительный размер компонента: если этого не сделать, он будет динамически менять свой размер в зависимости от размеров просматриваемого изображения, затрагивая остальной интерфейс, а это сделает работу пользователя некомфортной. Самое интересное происходит в методе propertyChange(), вызываемом при смене значения какого-либо привязанного свойства компонента JFileChooser. Мы следим за свойством, которое хранит имя выделенного в данный момент файла, название этого свойства содержится в константе

SELECTED_FILE_CHANGED_PROPERTY класса JFileChooser. Если свойство с этим названием поменялось, мы проводим следующие действия: проверяем, что новое значение свойства не равно пустой ссылке null (это происходит, когда пользователь обнуляет выделенный файл, например выделяя каталог или полностью сбрасывая выделение), и если это так, создаем новый значок ImageIcon, передавая ему имя нового выделенного файла, и устанавливаем для надписи JLabel полученный значок. Если вы помните, в главе 8 мы говорили, что надписи проводят автоматическую проверку корректности и перерисовку при смене своих свойств, так что вызова метода setIcon() будет достаточно для того, чтобы в нашем компоненте появилось новое изображение.

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

433

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

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

Выбор цвета в компоненте JColorChooser

Еще одно стандартное диалоговое окно, любезно предоставляемое нам Swing, реализовано в классе JColorChooser и предназначено для максимально быстрого (для программиста) и удобного (для пользователя) выбора цвета. Работать с компонентом JColorChooser так же просто, как и с компонентом для выбора файлов JFileChooser, а во многом и проще, так как возможностей тонкой настройки у JColorChooser куда меньше. Типичная схема выбора цвета такова: вы создаете объект класса JColorChooser и по мере необходимости выводите его на экран в диалоговом окне стандартного вида с помощью метода showDialog(), попутно задавая родительский компонент и заголовок окна. Рассмотрев пример, мы увидим, каким образом JColorChooser чаще всего применяется в программах:

//SimpleColorChooser.java

//Выбор цвета с помощью JColorChooser import javax.swing.*;

import java.awt.*; import java.awt.event.*;

public class SimpleColorChooser extends JFrame { public SimpleColorChooser() {

super("SimpleColorChooser"); setDefaultCloseOperation(EXIT_ON_CLOSE);

// кнопка выводит на экран окно выбора цвета

JButton choose = new JButton("Выбор цвета фона"); choose.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) { Color color = JColorChooser.showDialog(

SimpleColorChooser.this, "Выберите цвет фона",

getContentPane().getBackground()); // если цвет выбран, используем его

434

ГЛАВА 14

if ( color != null) getContentPane().setBackground(color);

repaint();

}

}); // выводим окно на экран

setLayout(new FlowLayout()); add(choose);

setSize(300, 200); setVisible(true);

}

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

new Runnable() {

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

}

}

В примере мы создаем небольшое окно, а компонент JColorChooser позволит нам выбрать цвет фона для панели содержимого. В качестве панели содержимого по умолчанию выступает простая панель JPanel, а она по умолчанию непрозрачна, то есть закрашивает все свое пространства цветом фона. Так что для смены цвета фона всего нашего окна нам достаточно будет сменить цвет фона панели содержимого, вызвав метод setBackground().

Объект JColorChooser, так же как и объект JFileChooser, может создаваться в программе единожды, а затем с большими или меньшими вариациями в настройке использоваться на протяжении всего времени ее работы. Это значительно ускоряет процесс появления диалогового окна на экране (если сравнивать с созданием объекта JColorChooser прямо перед выводом диалогового окна на экран) и экономит ресурсы, но требует от вас самостоятельно найти для него место на экране или создать диалоговое окно. С другой стороны, вывести стандартное диалоговое окно для выбора цвета на экран совсем просто: надо всего лишь вызвать статический метод showDialog(), которому передается три параметра. Первым параметром является родительский компонент диалогового окна (это может быть любой компонент, относительно него диалоговое окно располагается на экране), в качестве второго параметра вы задаете заголовок диалогового окна, а третьим параметром является цвет, изначально выбранный в компоненте JColorChooser. Третий параметр можно задать и пустой (null) ссылкой, в таком случае изначально цвета выбрано не будет. В ответ метод showDialog() (он выводит на экран модальное диалоговое окно, так что вам придется подождать, пока оно закончит свою работу) вернет вам цвет Color, который выбрал пользователь, или пустую (null) ссылку, если пользователь передумал и решил цвет не выбирать. В примере мы проверяем, что выбор был сделан, и устанавливаем выбранный цвет в качестве цвета фона.

В компоненте JColorChooser имеется возможность дополнительной настройки: к стандартным способам выбора цвета (из вполне приличного заранее определенного набора, с помощью цветовых моделей от RGB до CMYK) вы можете добавить собственную панель для выбора цвета, унаследовав ее от абстрактного класса AbstractColorChooserPanel из пакета javax.swing.colorchooser. Однако требуется это крайне редко: стандартные способы выбора цвета, представленные нам компонентом JColorChooser, достаточно хороши. Кроме того, вы можете присоединить к компоненту JColorChooser панель просмотра

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