WisdomSoft - for your serial experiences.

7.1 ファイル選択ダイアログ

実行システムのストレージからファイルを選択するダイアログを表示します。ダイアログに表示するファイルのアイコンやプレビューなど、ダイアログのカスタマイズが可能です。

7.1.1 ファイル選択コンポーネント

形に違いはあれども、多くのプラットフォーム、多くのアプリケーションで、ディスクやネットワーク上のリソースを参照するために、またはデータをディスクに書き込むために、ユーザーにファイルのパスと名前を入力させる専用のダイアログがサポートされています。ユーザーは、視覚的に木構造のファイルディレクトリを参照し、目的のファイルを発見することができるため、今ではビジネスアプリケーションにはなくてはならない存在です。

Swing では JDialog を拡張したファイル選択ダイアログクラスは存在せず、ファイルを選択するためのコンポーネント郡がコンテナにまとめられて一括提供されます。つまり、ファイル選択ダイアログではなくファイル選択コンポーネントが提供されているのです。これをファイルチューザと呼びます。

チューザは、選択する各種のコンポーネントを提供するコンテナとして提供する Swing コンポーネントです。ダイアログ以外のウィンドウや他のコンテナの子として利用できるため、よりスマートで柔軟性のある機能として再利用することができます。

ファイルチューザを利用するには javax.swing.JFileChooser クラスを利用します。

javax.swing.JFileChooser クラス
java.lang.Object
  |
  +--java.awt.Component
        |
        +--java.awt.Container
              |
              +--javax.swing.JComponent
                    |
                    +--javax.swing.JFileChooser
public class JFileChooser extends JComponent implements Accessible

このクラスは JComponent クラスを継承しているため Swing コンポーネントとして扱うことができます。このクラスのインスタンスをウィンドウなどのコンテナに追加すると、ファイル選択用のコンテナとして利用することができるようになります。モーダルダイアログに表示すれば、ファイル選択ダイアログとして使えるでしょう。

表1 JFileChooser クラスのコンストラクタとメソッド(抜粋)
コンストラクタ 解説
public JFileChooser() ユーザのデフォルトディレクトリを参照する JFileChooser を構築する。
public JFileChooser(String currentDirectoryPath) 指定されたパスを使用して JFileChooser を構築する。
public JFileChooser(File currentDirectory) 指定された File をパスに使用して JFileChooser 構築する。
public JFileChooser(FileSystemView fsv) 指定された FileSystemView を使って JFileChooser を構築する。
public JFileChooser(File currentDirectory, FileSystemView fsv) 指定されたパスと FileSystemView を使って JFileChooser を構築する。
public JFileChooser(String currentDirectoryPath, FileSystemView fsv) 指定されたパスと FileSystemView を使って JFileChooser を構築する。
メソッド
public void addActionListener(ActionListener l) ファイルチューザに ActionListener を追加する。
public void removeActionListener(ActionListener l) ファイルチューザから ActionListener を削除する。
public ActionListener[] getActionListeners() 設定されているすべての ActionListener の配列を返す。
public void setSelectedFile(File file) 選択されたファイルを設定する。
public File getSelectedFile() 選択されたファイルを返す。
public void setSelectedFiles(File[] selectedFiles) 選択されたファイルのリストを設定する。
public File[] getSelectedFiles() 選択されたファイルのリストを返す。
public void setCurrentDirectory(File dir) 現在のディレクトリを設定する。
public File getCurrentDirectory() 現在のディレクトリを返す。
public void setMultiSelectionEnabled(boolean b) true を設定すると複数ファイル選択を許可する。
public boolean isMultiSelectionEnabled() 複数のファイルを選択できる場合に true を返す。

表1は JFileChooser のコンストラクタと選択に関連する基本的なメソッドです。コンストラクタでは FileSystemView クラスのオブジェクトを設定することができますが、このクラスはプラットフォーム固有のファイルシステムに関するより具体的な情報を提供するためのものです。隠しファイルやファイルの種類などの情報をファイルチューザに提供することができますが、通常はアプリケーションが独自に拡張する必要はありません。

ファイルチューザは、通常は 1 つのファイルを選択するために利用されますが、setMultiSelectionEnabled() メソッドの設定で複数のファイルを選択することもできます。複数のファイルを選択している場合は、setSekectedFiles() メソッド getSelectedFiles() メソッドで選択の制御を配列として処理する必要があります。

ファイルチューザは、選択を了承するボタンと、選択を取り消す 2 つのボタンを保有しています。これらのボタンを押すなどして、ファイルを選択するとチューザに登録されているアクションリスナが呼び出されます。アクションが選択されたものなのか、取り消されたものなのかの区別は、イベント引数が保有するアクションコマンドを getActionCommand() から取得して判断します。戻り値が JFileChooser.APPROVE_SELECTION であれば選択、JFileChooser.CANCEL_SELECTION であれば取り消しを意味します。

コード1
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame implements ActionListener {
	public static void main(String args[]) {
		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.show();
	}

	private JFileChooser filec = new JFileChooser();
	private JLabel label = new JLabel("ファイルを選択してください");
	public Test() {
		filec.addActionListener(this);

		getContentPane().add(filec , BorderLayout.CENTER);
		getContentPane().add(label , BorderLayout.SOUTH);
	}

	public void actionPerformed(ActionEvent e) {
		if (filec.getSelectedFile() == null) return;
		label.setText(
			e.getActionCommand() + "=" +
			filec.getSelectedFile().getPath()
		);
	}
}
実行結果
コード1 実行結果

コード1は、アプリケーションウィンドウに直接ファイルチューザを貼り付けています。ファイルチューザは Swing 軽量コンポーネントに属しているため、このように他のコンテナの一部として機能させることができます。プログラムでは、ファイルを選択するとチューザに登録しているアクションリスナが呼び出され、このタイミングでウィンドウの下部に表示されているラベルにチューザが選択したファイルを表示します。

7.1.2 選択ボタンのカスタマイズ

コード1の実行結果を見てわかるように、ファイルの選択を決定するボタンコンポーネントの内容が「開く」 とされていますが、この文字列は常に適当であるとは限りません。代表的なチューザの利用方法の 1 つと考えられる保存するファイルの選択ダイアログでは、「開く」 ボタンよりも 「保存」 ボタンのほうが適当です。

ファイルチューザでフィアルを選択することを表すボタンを Approve ボタンと呼びます。このボタンが表示するテキストを変更するには setApproveButtonText() メソッドを、取得するには getApproveButtonText() メソッドを使います。

JFileChooser クラス setApproveButtonText() メソッド
public void setApproveButtonText(String approveButtonText)
JFileChooser クラス getApproveButtonText() メソッド
public String getApproveButtonText()

setApproveButtonText() メソッドで、ファイルチューザの目的に合わせた Approve  ボタンを表示することができます。ただし、Approve ボタンの上でカーソルを待機させるとツールチップが表示されるのですが、この内容がボタンのテキストと食い違ってしまうと奇妙です。Approve ボタンのテキストを変更する場合は、合わせてツールチップの内容も変更してください。ツールチップの文字列を設定するには setApproveButtonToolTipText() メソッドを、現在のツールチップのテキストを得るには getApproveButtonToolTipText() メソッドを使います。

JFileChooser クラス setApproveButtonToolTipText() メソッド
public void setApproveButtonToolTipText(String toolTipText)
JFileChooser クラス getApproveButtonToolTipText() メソッド
public String getApproveButtonToolTipText()

toolTipText パラメータには Approve ボタンが表示するツールチップの内容を指定してください。

コード2
import java.awt.*;
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		JFileChooser filec = new JFileChooser();
		filec.setApproveButtonText("Kitty");
		filec.setApproveButtonToolTipText("仔猫の可愛さは世界一ィィィィ");

		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.getContentPane().add(filec);
		win.show();
	}
}
実行結果
コード2 実行結果

コード2は、独自の Approve ボタンと、このボタンが表示するツールチップを設定してます。結果は実行結果の通りです。

7.1.3 ダイアログとして表示する

JFileChooser が軽量コンポーネントとして扱うことができるとは言え、役割から考えるとファイルチューザのほとんどはモーダルダイアログのコンテナに表示されるでしょう。そして、ファイルが正しく選択されるか、取り消された時点でそれを結果として返す形が望まれます。

幸い、独自に JDialog クラスを継承しなくても、JFileChooser クラスには自らをファイルチューザとして含んだダイアログを表示させ、結果を返す一連の作業を行う showDialog() メソッドが用意されています。また、このメソッドに付随してファイルを開くための showOpenDialog() メソッドと、ファイルを保存するための showSaveDialog() メソッドも存在します。ファイルチューザをダイアログとして表示し、結果を受け取りたいのであれば、これらメソッドを使うと便利でしょう。

JFileChooser クラス showOpenDialog() メソッド
public int showOpenDialog(Component parent) throws HeadlessException
JFileChooser クラス showSaveDialog() メソッド
public int showSaveDialog(Component parent) throws HeadlessException
JFileChooser クラス showDialog() メソッド
public int showDialog(Component parent, String approveButtonText) throws HeadlessException

parent パラメータにはダイアログを所有する親コンポーネントを指定することができますが null を指定することもできます。approveButtonText パラメータには Approve ボタンに遣われるテキストを設定します。これらのメソッドは HeadlessException 例外をスローする可能性を持ちます。この例外は、システムがディスプレイ、キーボード、マウスの基本デバイスをサポートしていない場合に発生します。

ユーザーが適切にファイルを選択することができたかどうかは、メソッドの戻り値から判断することができます。戻り値が JFileChooser.APPROVE_OPTION であれば、Approve ボタンを押すなどして、正常に選択されたことを意味します。後は、チューザから getSelectedFile() メソッドを使うなどして、選択したファイルを取得することができるでしょう。

コード3
import javax.swing.*;

public class Test {
	public static void main(String args[]) {
		JFileChooser filec = new JFileChooser();
		if (JFileChooser.APPROVE_OPTION == filec.showOpenDialog(null)) {
			System.out.println("ファイルが選択されました");
			System.out.println("\t" + filec.getSelectedFile());
		}
		else System.out.println("選択は中断されました");

		System.exit(0);
	}
}

コード3の main() メソッドでは、ウィンドウを生成することなく JFileChooser クラスのインスタンスを生成し、そのまま showOpenDialog() メソッドからダイアログを表示して結果を標準出力に表示するプログラムです。この機能を用いれば、アプリケーションが出力するデータのパスをユーザーに選択させるといった処理が容易になるでしょう。

7.1.4 ファイルフィルタ

ファイルチューザから何らかのファイルを開いたり、保存したりするとき、必ずしもすべてのファイルが対象になるわけではありません。例えば、ガゾウビューワアプリケーションを開発しているのであれば、ファイルを開くダイアログの目的は画像ファイルを選択することです。画像ファイルの拡張子は jpg や gif、png などが考えられますが、txt や exe の可能性はほとんどありません。ならば、ファイルチューザが表示するファイルは特定の拡張子を持つファイルだけに絞ったほうが、選択するユーザーも目的のファイルを探しやすくなります。

ファイルチューザはファイルを表示するかどうかを判断するオブジェクトを複数登録することができ、これをファイルフィルタとして利用することができます。ファイルが表示されようとすると、選択されているファイルフィルタのメソッドが呼び出され、そのファイルを表示するかどうかを表す論理値を返すという仕組みが採用されています。そのため、ファイル拡張子だけではなく、ファイルの具体的な内容や、ファイルサイズ、更新日など様々な要因で表示するかしないかを判断することができるでしょう。

ファイルフィルタは、インタフェースではなく javax.swing.filechooser.FileFilter クラスとして定義されています。独自のファイルフィルタを作成するには、このクラスを継承します。

javax.swing.filechooser.FileFilter クラス
java.lang.Object
  |
  +--javax.swing.filechooser.FileFilter
public abstract class FileFilter extends Object

このクラスは抽象クラスとして定義されているため、インスタンスを生成することはできません。このクラスが定義しているメソッドは、指定されたファイルを表示するかどうかを決定する accept() メソッドと、このフィルタ自身の説明を返す getDescription() メソッドだけです。

FileFilter クラス accept() メソッド
public abstract boolean accept(File f)
FileFilter クラス getDescription() メソッド
public abstract String getDescription()

accept() メソッドは、f パラメータに渡されたファイルを表示するかどうかを戻り値で返します。true を返せば、そのファイルはファイルチューザの選択リストに表示されるでしょう。

作成したファイルフィルタをファイルチューザに追加するには addChoosableFileFilter() メソッドを、解除するには removeChoosableFileFilter() メソッドを使います。ファイルフィルタリストを開始時の状態にリセットするには resetChoosableFileFilters() メソッドを呼び出してください。設定されているファイルフィルタは getChoosableFileFilters() メソッドから得ることができます。

JFileChooser クラス addChoosableFileFilter() メソッド
public void addChoosableFileFilter(FileFilter filter)
JFileChooser クラス removeChoosableFileFilter() メソッド
public boolean removeChoosableFileFilter(FileFilter f)
JFileChooser クラス resetChoosableFileFilters() メソッド
public void resetChoosableFileFilters()
JFileChooser クラス getChoosableFileFilters() メソッド
public FileFilter[] getChoosableFileFilters()

addChoosableFileFilter() メソッドを使えば、ファイルチューザの「ファイルタイプ」コンボボックスにファイルフィルタが追加されます。ファイルチューザに選択されているファイルフィルタをプログラムから設定するには setFileFilter() メソッドを、現在設定されているフィルタを取得するには getFileFilter() メソッドを使います。

JFileChooser クラス setFileFilter() メソッド
public void setFileFilter(FileFilter filter)
JFileChooser クラス getFileFilter() メソッド
public FileFilter getFileFilter()

filter パラメータに、ファイルチューザに選択する新しいファイルフィルタを設定します。

コード4
import javax.swing.*;
import javax.swing.filechooser.*;

public class Test {
	public static void main(String args[]) {
		ExtensionFileFilter filter[] = {
			new ExtensionFileFilter(".jpg" , "JPEG ファイル(*.jpg)") ,
			new ExtensionFileFilter(".gif" , "GIF ファイル(*.gif)") ,
			new ExtensionFileFilter(".png" , "PNG ファイル(*.png)")
		};

		JFileChooser filec = new JFileChooser();
		for(int i = 0 ; i < filter.length ; i++)
			filec.addChoosableFileFilter(filter[i]);
		filec.setFileFilter(filter[0]);
		filec.showOpenDialog(null);
		System.exit(0);
	}
}

class ExtensionFileFilter extends FileFilter {
	private String extension , msg;
	public ExtensionFileFilter(String extension , String msg) {
		this.extension = extension;
		this.msg = msg;
	}
	public boolean accept(java.io.File f) {
		return f.getName().endsWith(extension);
	}
	public String getDescription() { return msg; }
}
実行結果
コード4 実行結果

コード4は、独自のファイルフィルタ ExtensionFileFilter クラスを定義し、これをファイルフィルタとして設定しています。このファイルフィルタは、与えられたファイルの末尾の名前が指定されている拡張子かどうかを判断し、拡張子が一致する場合の未表示を許可します。

7.1.5 ファイルビュー

ファイルチューザが表示する個々のファイルのアイコンは、ディレクトリを表すアイコンとファイルを表すアイコンの 2 種類だけでした。多くのグラフィカルなネイティブシステムは、ファイルの種類を視覚的に認識できるようにアイコンをファイルタイプごとに用意しています。イメージファイルならイメージを連想するようなアイコン、実行ファイルなら実行ファイルを連想させるアイコンを設定しているでしょう。しかし、システムを固定しない Java ではネイティブシステムのアイコンの設定を関連付けることができないため、このように独自のアイコンを表示しているのです。

しかし、アプリケーションを利用するユーザーにとっていは、ファイルの種類をアイコンや説明文などでアピールしてくれたほうが直観的に目的のファイルを見つけることができます。どう見ても Swing デフォルトのファイルチューザはユーザーに優しいものではありません。

そこで、ファイルチューザは表示する選択対象のファイルの表示方法を独自に拡張する手段を提供しています。この方法を利用すれば、リストのセルレンダラのように個々のファイルの描画方法をカスタマイズすることができます。例えば、ファイル拡張子を隠蔽して表示したり、ファイルの種類によってアイコンを表示することができるようになるのです。

独自の方法でファイルチューザに表示されるファイル項目を描画するにはファイルビューを拡張します。ファイルビューは javax.swing.filechooser.FileView クラスで定義されてます。

javax.swing.filechooser.FileView クラス
java.lang.Object
  |
  +--javax.swing.filechooser.FileView
public abstract class FileView extends Object

FileView クラスは抽象クラスなので、このクラスを拡張することでファイル項目の表示方法をカスタマイズすることができるようになります。FileView クラスで宣言されているメソッドをオーバーライドすることで、表示されるファイルのアイコンやファイル名を変更することができます。

表2 FileView クラスのメソッド
メソッド 解説
public String getDescription(File f) ファイルの説明を返す。
public String getTypeDescription(File f) ファイルの種類の説明を返す。
public String getName(File f) ファイルの名前を取得する。通常は f.getName() を返す。
public Icon getIcon(File f) このファイルを表すアイコンを返す。
public Boolean isTraversable(File f) ディレクトリに移動可能かどうかを返す。

ファイルチューザによってファイルが表示されようとすると、FileView オブジェクトの各メソッドに表示するファイルの File オブジェクトが渡されます。FileView オブジェクトは与えられた File オブジェクトからファイルの種類や状態を取得して、適切な結果を返さなければなりません。例えば、表示されるアイコンは getIcon() メソッド、表示されるテキストは getName() メソッドが返した値が利用されます。

FileView を継承したクラスは必要なメソッドをオーバーライドし、与えられた File オブジェクトに興味があるかどうかを調べ、そのファイルに興味があるのならば独自の処理結果を返し、興味がない場合はデフォルトの FileView クラスのメソッドを呼び出してその結果を返すと良いでしょう。そうすれば、デフォルトの動作と互換性を保ちながら独自の拡張を実現することができます。

ファイルチューザにユーザー定義のファイルビューを設定するには setFileView() メソッドを利用します。現在設定されているファイルビューを取得したければ getFileView() メソッドを使ってください。

JFileChooser クラス setFileView() メソッド
public void setFileView(FileView fileView)
JFileChooser クラス getFileView() メソッド
public FileView getFileView()

setFileView() メソッドから FileView クラスを拡張した独自のファイルビューを設定すれば、オーバーライドしたメソッドが呼び出され、ファイルチューザが表示するファイル項目の情報を制御することができます。

コード5
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.swing.filechooser.*;

public class Test {
	public static void main(String args[]) {
		IconFileView fileView = new IconFileView();
		fileView.setDirectoryIcon(new ImageIcon("directory.jpg"));
		fileView.add(".jpg" , new ImageIcon("image.jpg"));

		JFileChooser filec = new JFileChooser();
		filec.setFileView(fileView);
		filec.showOpenDialog(null);
		System.exit(0);
	}
}

class IconFileView extends FileView {
	Hashtable table = new Hashtable();
	Icon directoryIcon = null;

	public void add(String extension , Icon icon) {
		table.put(extension , icon);
	}
	public void remove(String extension) {
		table.remove(extension);
	}

	public void setDirectoryIcon(Icon icon) { this.directoryIcon = icon; }
	public Icon getDirectoryIcon() { return directoryIcon; }

	public Icon getIcon(File f) {
		if (f.isDirectory()) return directoryIcon;

		Enumeration enum = table.keys();
		while(enum.hasMoreElements()) {
			String key = enum.nextElement().toString();
			if (f.getName().endsWith(key)) return (Icon)table.get(key);
		}
		return super.getIcon(f);
	}
}
実行結果
コード5 実行結果

コード5は独自のファイルビューを定義してファイルチューザに設定しています。IconFileView クラスはファイルの拡張子と Icon オブジェクトを関連付ける機能を提供しています。また、ディレクトリのアイコンも設定することができます。プログラムでは、ディレクトリ用のアイコンと JPEG イメージのアイコンをそれぞれ設定しています。ファイルチューザからアイコンが要求されると、File オブジェクトを調べてそれがディレクトリである場合はディレクトリ用のアイコンを、そうでなければファイルの拡張子を調べ、その拡張子がアイコンと関連付けられている場合はアイコンを返します。そうでなければ、スーパークラスに処理を委ねています。

このプログラムでは、拡張子が jpg の場合に実行結果のようなキャラクター画像を表示しています。ただし、IconFileView クラスは拡張子の大文字と小文字を区別してしまいます。拡張子とアイコンの関連付けは Hashtable クラスを利用しているので、任意の数のアイコンを設定することができますが、一般的には大文字と小文字を区別する必要はないでしょう。String クラスの toLowerCase() や toUpperCase() を使えば大文字か小文字に統一することができます。

7.1.6 アクセサリ

ファイルチューザには、選択しているファイルの情報を表示するなど、ユーザーに情報を提供したり、対話を行うための専用コンポーネントを付加することができます。これをアクセサリと呼び、JComponent を継承してくるクラスであれば、どのようなコンポーネントでもアクセサリに登録することができます。例えば、選択しているファイルがイメージファイルのとき、そのイメージのサムネイル画像を表示するコンポーネントをアクセサリとして利用することができます。

アクセサリ用のコンポーネントをファイルチューザに登録するには setAccessory() メソッドに JComponent オブジェクトを渡します。現在設定されているアクセサリを取得するには getAccessory() メソッドを使います。

JFileChooser クラス setAccessory() メソッド
public void setAccessory(JComponent newAccessory)
JFileChooser クラス getAccessory() メソッド
public JComponent getAccessory()

newAccessory パラメータに新しく設定するアクセサリ用のコンポーネントを設定します。このコンポーネントには適切な推奨サイズを設定して置いてください。ファイルチューザが表示するアクセサリがどのような目的で使われるかはコンポーネントの開発者に委ねられています。

一般的には、画像ファイルの簡易表示やファイル情報の表示など、ファイルチューザの選択状態などに応じて何らかの動作を行うコンポーネントが用いられるでしょう。ファイルチューザの状態によって変化するコンポーネントを実現するには、ファイルチューザに PropertyChangeListener を追加してファイルチューザのプロパティを監視し、選択状態が変更されたタイミングでファイルチューザから必要な情報を受け取り、その結果を表示するようにプログラムします。

コード6
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.beans.*;
import java.io.*;

public class Test extends JFrame implements PropertyChangeListener {
	public static void main(String args[]) {
		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.show();
	}

	private JFileChooser filec = new JFileChooser();
	private ImageThumbnail accessory = new ImageThumbnail();
	public Test() {
		accessory.setBorder(new BevelBorder(BevelBorder.LOWERED));
		accessory.setPreferredSize(new Dimension(200 , 200));

		filec.setAccessory(accessory);
		filec.addPropertyChangeListener(this);
		getContentPane().add(filec , BorderLayout.CENTER);
	}
	public void propertyChange(PropertyChangeEvent e) {
		File file = filec.getSelectedFile();
		if (file == null) return;

		Image image = Toolkit.getDefaultToolkit().getImage(file.getPath());
		accessory.setImage(image);
	}
}

class ImageThumbnail extends JComponent {
	Image image;

	public void setImage(Image image) {
		this.image = image;
		repaint();
	}
	public Image getImage() { return this.image; }

	public void paintComponent(Graphics g) {
		if (image == null) {
			super.paintComponent(g);
			return;
		}

		Dimension size = new Dimension();
		int width = image.getWidth(this) , height = image.getHeight(this);

		if (getWidth() < getHeight()) {
			if ((getWidth() * height / width) < getHeight())
				size.setSize(getWidth() , getWidth() * height / width);
			else size.setSize(getHeight() * width / height , getHeight());
		}
		else {
			if ((getHeight() * width / height) < getWidth())
				size.setSize(getHeight() * width / height , getHeight());
			else size.setSize(getWidth() , getWidth() * height / width);
		}
		g.drawImage(image ,
			getWidth() / 2 - size.width / 2 ,
			getHeight() / 2 - size.height / 2,
			size.width , size.height , this
		);

		super.paintComponent(g);
	}
}
実行結果
コード6 実行結果

コード6は、設定された Image オブジェクトを縦横の比率をそのままに、コンポーネントのサイズに縮小して表示するサムネイル画像表示用の ImageThumbnail クラスを定義しています。このコンポーネントをファイルチューザにアクセサリとして追加しています。

PropertyChangeListener をファイルチューザに登録しているため、ファイルチューザのプロパティが変更されるとメソッドが呼び出されます。このタイミングでファイルチューザが現在選択しているファイルのパスを取得し、このファイルからイメージの生成を試みます。画像を読み込むことができれば、サムネイルに画像が表示され、生成が失敗すると null が設定されるため画像は表示されません。