WisdomSoft - for your serial experiences.

9.6 オプションペイン

簡易なテキストメッセージや、処理を実行するかどうかを確認する「OK」「キャンセル」ボタン付きのウィンドウを表示するにはオプションペインを使うと便利です。

9.6.1 ダイアログ用のコンテナ

Windows API を学習したことがあれば MessageBox() という API を知っているでしょう。これは、Windows でよく見られる警告用のダイアログなどを表示するために Windows が開発者に提供している機能ですが、こうした性質の関数は非常に重要な存在です。

ちょっとしたエラーメッセージやアプリケーションのバージョン情報など、簡単な情報をユーザーに通知する場合でも、GUI アプリケーションであれば新しいダイアログボックスを作ったり、新しいウィンドウやコンポーネントを作成して表示しなければなりません。これでは、単純な情報を簡潔に表示したり、デバッグで変数の値などを表示するだけの処理のために面倒なコードを記述しなければなりません。

Swing は、この問題を解決するために、情報ダイアログのレイアウトを提供するオプションペインと呼ばれるコンテナを提供してます。javax.swing.JOptionPane クラスを使うことで簡単に実装することができるでしょう。

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

このコンテナは、一般的な情報ダイアログボックスに必要なアイコン、表示オブジェクト、オプションボタンなどを提供しています。入力値を表すプロパティも提供されているため、入力用ダイアログとして利用することもできます。

表1 JOptionPane クラスのコンストラクタとメソッド(抜粋)
コンストラクタ 解説
public JOptionPane() テストメッセージを含む JOptionPane を生成する。
public JOptionPane(Object message) メッセージを表示する JOptionPane のインスタンスを生成する。
public JOptionPane(Object message, int messageType) 指定されたメッセージタイプおよびメッセージを表示する JOptionPane のインスタンスを生成する。
public JOptionPane(Object message, int messageType, int optionType) 指定されたメッセージタイプ、オプション、メッセージを表示するための JOptionPane のインスタンスを生成する。
public JOptionPane(Object message, int messageType, int optionType, Icon icon) 指定されたメッセージタイプ、オプション、アイコン、メッセージを表示するための JOptionPane のインスタンスを生成する。
public JOptionPane(Object message, int messageType, int optionType, Icon icon, Object[] options) 指定されたメッセージタイプ、アイコン、オプション、メッセージ、選択項目を表示するための JOptionPane のインスタンスを生成する。
public JOptionPane(Object message, int messageType, int optionType, Icon icon, Object[] options, Object initialValue) 指定されたメッセージタイプ、アイコン、オプション、メッセージを表示し、選択項目と初期状態で選択されている項目を設定した JOptionPane のインスタンスを生成する。
メソッド
public void setMessage(Object newMessage) メッセージオブジェクトを設定する。
public Object getMessage() メッセージオブジェクトを返す。
public void setMessageType(int newType) メッセージタイプを設定する。
public int getMessageType() メッセージタイプを返す。
public void setIcon(Icon newIcon) 表示するアイコンを設定する。
public Icon getIcon() この区画が表示するアイコンを返す。
public void setValue(Object newValue) ユーザが選択した値を設定する。
public Object getValue() ユーザが選択した値を返す。
public void setOptions(Object[] newOptions) この区画が表示するオプションを設定する。
public Object[] getOptions() ユーザが作成可能な項目を返す。
public void setOptionType(int newType) 表示するオプションを設定する。
public int getOptionType() 表示されるオプションのタイプを返す。
public void setInitialValue(Object newInitialValue) 有効にすべき初期値を設定する。
public Object getInitialValue() 初期値を返す。
public void setSelectionValues(Object[] newValues) 選択項目リストの入力選択値を設定する。
public Object[] getSelectionValues() 入力選択値を返す。
public void setInputValue(Object newValue) ユーザによって選択または入力された入力値を設定する。
public Object getInputValue() ユーザが入力した数値を返す。
public void setWantsInput(boolean newValue) wantsInput プロパティを設定する。
public boolean getWantsInput() wantsInput プロパティの値を返します。

JOptionPane は重要なプロパティを多く持っていますが、これらを上手く応用すれば、データをユーザーに表示したり、ユーザーに何らかのデータの入力や選択を要求する処理を、短いコードで実現することができるようになります。

オプションペインの基本となるのは、アイコン、メッセージ、そしてオプションボタンです。この 3 つのデータを表示するだけで、多くのプラットフォームで使われている、いわゆるメッセージボックスを Java で実現することができるのです。

図1 オプションペインの構造
図1 オプションペインの構造

オプションボタンは、setOptions() メソッドからユーザー定義のボタンを追加することができます。与えられたオブジェクトが Component 型に互換性がある場合はそのコンポーネントを表示し、そうでなければ、与えられたオブジェクトを表示するボタンが作られます。

さらに、このコンテナが表示するメッセージがどのような性質のものなのかを setMessageType() メソッド、またはコンストラクタから具体的に設定することができます。このメソッドに渡す数値は、JOptionPane クラスで公開されているフィールド定数のうち、エラーを表すERROR_MESSAGE、情報メッセージを表す INFORMATION_MESSAGE、警告メッセージを表す WARNING_MESSAGE、質問メッセージを表す QUESTION_MESSAGE、または標準メッセージを表す PLAIN_MESSAGE のいずれかをしてします。アイコンを明示的に設定していない場合は、これらの情報から標準アイコンを決定します。

同様に、オプション区画に表示するボタンを、コンストラクタか setOptionType() メソッドから設定することができます。このプロパティに指定する値は JOptionPane クラスのフィールド定数のうち、DEFAULT_OPTION、YES_NO_OPTION、YES_NO_CANCEL_OPTION、OK_CANCEL_OPTION のいずれかです。デフォルトでは OK ボタンだけが表示されるでしょう。

コード1
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		JOptionPane pane = new JOptionPane();
		pane.setMessage("メッセージです");
		pane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
		pane.setIcon(new ImageIcon("icon1.jpg"));
		pane.setOptionType(JOptionPane.YES_NO_OPTION);

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

コード1は、JOptionPane クラスのインスタンスを生成し、メソッドからメッセージとメッセージタイプ、アイコンとオプション区画に表示するボタンを設定しています。通常、メッセージとして渡したオブジェクトはその文字列表現が表示されるため、一般的には文字列型を渡します。

オプションボタンが押された結果は、getValue() メソッドを通じて取得することができます。何らかのオプションをプログラムから選択する場合は setValue() メソッドを使います。OK ボタンが押された場合は JOptionPane クラスのフィールドで定義されている OK_OPTION が設定されます。YES ボタンであれば YES_OPTION、NO ボタンであれば NO_OPTION という具合になります。getValue() で得られる値は Object 型ですが、これらのフィールド定数は int 型として宣言されています。比較を行う場合は int 型を Integer 型に変換し equals() メソッドで行う必要があります。

ユーザーに何らかのデータを選択してもらうか、文字列を入力してもらう場合は setWantsInput() メソッドに true を指定します。そうすれば、リスト、またはテキストコンポーネントが表示され、データを選択することができます。入力データは setInputValue() メソッドから設定することもできます。入力されたデータを取得するには getInputValue() メソッドから取得すると良いでしょう。

9.6.2 ダイアログの生成

JOptionPane クラスは、性質的にダイアログボックスに追加されて利用される可能性が高いと考えられます。そこで、JOptionPane クラスはこのコンテナを配置している JDialog インスタンスを自動生成したり、直接ダイアログを表示するメソッドをいくつか提供しています。

JOptionPane コンテナを配置するダイアログを生成すには JOptionPane クラスの createDialog() メソッドを使います。

JOptionPane クラス createDialog() メソッド
public JDialog createDialog(
	Component parentComponent, String title) throws HeadlessException

parentComponent パラメータには、生成するダイアログの親となるコンポーネントを指定します。通常 Frame オブジェクトを指定しなければならないのですが、この値に Frame 型との互換性が存在しない場合は Swing の共通フレームが利用されます。title パラメータには、ダイアログのタイトルとして表示される文字列を指定します。

コード2
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		JOptionPane pane = new JOptionPane();
		pane.setMessage("メッセージです");
		pane.setMessageType(JOptionPane.QUESTION_MESSAGE);
		pane.setOptionType(JOptionPane.YES_NO_OPTION);
		pane.setWantsInput(true);

		JDialog dialog = pane.createDialog(null , "Kitty");
		dialog.show();
		if (pane.getValue().equals(new Integer(JOptionPane.YES_OPTION)))
			System.out.println("YES:" + pane.getInputValue());
		else System.out.println("NO:" + pane.getInputValue());

		System.exit(0);
	}
}

コード2は、JOptionPane インスタンスのメッセージなどの基本情報を設定した後、createDialog() メソッドを使ってオプションペインを用事するダイアログを生成しています。このメソッドが返す JDialog インスタンスには、すでにこのコンテナが追加されているので、そのまま表示して利用することができます。このダイアログは、一度閉じるかまたはユーザがボタンのどれかをクリックすると、オプション区画の値プロパティがそれに応じて設定されてダイアログが閉じられるように設定されます。

このプログラムでは、ダイアログを show() メソッドで表示し、ユーザーが値を入力して、オプションボタンを選択するのを待ちます。その後、getValue() メソッドを使って、押されたボタンが YES ボタンであるかどうかを調べています。結果は、標準出力に表示されるでしょう。

JOptionPane クラスの静的メソッドには、インスタンスを生成することなく、直接オプションペインを表示するモーダルダイアログを表示してくれるメソッドが存在します。このメソッドはいくつかに分かれていますが、最も単純なのはメッセージを表示するだけの showMessageDialog() メソッドです。

JOptionPane クラス showMessageDialog() メソッド
public static void showMessageDialog(
	Component parentComponent, Object message
) throws HeadlessException
public static void showMessageDialog(
	Component parentComponent, Object message,
	String title, int messageType
) throws HeadlessException
public static void showMessageDialog(
	Component parentComponent, Object message,
	String title, int messageType, Icon icon
) throws HeadlessException

これらのメソッドで表示するダイアログは OK ボタンをオプション区画に表示するダイアログで、単純なメッセージを表示するだけです。icon パラメータを指定すればそのアイコンが表示され、そうでなければ messageType パラメータに指定されたメッセージタイプに基づいた標準アイコンが利用されます。

YES ボタンの NO ボタンが表示される、選択可能なダイアログを表示するには showConfirmDialog() メソッドを使います。基本的には showMessageDialog() と同じですが、押されたオプションボタンを表す値を返す点で異なります。

JOptionPane クラス showConfirmDialog() メソッド
public static int showConfirmDialog(
	Component parentComponent, Object message
) throws HeadlessException
public static int showConfirmDialog(
	Component parentComponent, Object message,
	String title, int optionType
) throws HeadlessException
public static int showConfirmDialog(
	Component parentComponent, Object message,
	String title, int optionType, int messageType
) throws 	HeadlessException
public static int showConfirmDialog(
	Component parentComponent, Object message,
	String title, int optionType, int messageType, Icon icon
) throws HeadlessException

これらのメソッドでは optionType パラメータが追加されていて、このパラメータから表示するオプションボタンを設定することができます。デフォルトでは YES_NO_CANCEL_OPTION が設定されていますが、YES_NO_OPTION を設定することもできます。ダイアログが閉じられ、このメソッドが制御を返すと、戻り値から選択されたボタンを調べることができます。

さらに、ユーザーに入力を求めるダイアログを表示させる showInputDialog() メソッドも提供されています。このメソッドは、ユーザーに単純な文字列などを入力してもらいたい場合に利用できるでしょう。

JOptionPane クラス showInputDialog() メソッド
public static String showInputDialog(Object message) throws HeadlessException
public static String showInputDialog(Object message, Object initialSelectionValue)
public static String showInputDialog(
	Component parentComponent, Object message
) throws HeadlessException
public static String showInputDialog(
	Component parentComponent, Object message,
	Object initialSelectionValue
)
public static String showInputDialog(
	Component parentComponent, Object message,
	String title, int messageType
) throws HeadlessException
public static Object showInputDialog(
	Component parentComponent, Object message, String title,
	int messageType, Icon icon, Object[] selectionValues, Object initialSelectionValue
) throws HeadlessException

showInputDialog() メソッドも多くオーバーロードされていますが、基本的にはユーザーに入力してもらった文字列を結果として返すという以外は、メッセージダイアログと大きな差はありません。initialSelectionValue パラメータを指定すると、この値を用いて入力フィールドが初期化されます。Object [] 配列を selectionValuesパラメータで指定すると、このオブジェクトの配列のいずれかが選択できるリストが表示されます。この場合、メソッドは選択されたオブジェクトを戻り値として返します。

コード3
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		if (JOptionPane.showConfirmDialog(
			null , "メッセージ" , "タイトル" ,
			JOptionPane.YES_NO_OPTION
		) == JOptionPane.YES_OPTION)
			System.out.println("YES が選択されました");
		else System.out.println("NO が選択されました");

		System.exit(0);
	}
}

コード3は、単純な選択ダイアログを表示します。YES ボタンか NO ボタンのいずれかを押してダイアログが閉じられると、標準出力にどちらのボタンが押されたのかが表示されるという単純なプログラムです。コンテナやダイアログを生成し、これを表示する処理を 1 つのメソッドで実現できる点が魅力的です。

JOptionPane クラスには、ダイアログを表示する静的メソッドが多く宣言されていますが、これらのメソッドは最終的に showOptionDialog() メソッドだけで実現させることができます。showOptionDialog() メソッドは、引数から JOptionPane クラスの主要なプロパティをすべて設定することができる汎用的なメソッドです。

JOptionPane クラス showOptionDialog() メソッド
public static int showOptionDialog(
	Component parentComponent, Object message,
	String title, int optionType, int messageType,
	Icon icon, Object[] options, Object initialValue
) throws HeadlessException

parentComponent パラメータには、ダイアログの親となる Frame オブジェクトを、message パラメータにはメッセージとして表示するオブジェクト、title パラメータにはダイアログのタイトル、optionType パラメータにはオプション区画に表示するボタンを選択する整数、messageType パラメータはメッセージタイプ、icon パラメータには表示するアイコン、options パラメータには選択可能な項目を表すオブジェクトの配列、initalValue パラメータにはダイアログのデフォルト選択を示すオブジェクトを指定します。

これまで説明してきた JOptionDialog クラスの基本的な動作は、このメソッドだけで実現することができるでしょう。