ダイアログを表示するにはJDialogを使う。
ダイアログ内にラベルや入力エリア等を配置する方法はJFrameと同じ。
public class SampleDialog extends JDialog {
public SampleDialog(Frame owner) {
super(owner);
setTitle("ダイアログのサンプル");
setBounds(64, 64, 256, 256);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// ダイアログに表示するコンポーネントを設定
Container c = getContentPane();
c.add(new JLabel("ラベル"));
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("ダイアログを出すフレーム");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(32, 32, 256, 256);
// コンテナに“ダイアログを出すボタン”を追加
Container c = frame.getContentPane();
c.setLayout(new FlowLayout());
c.add(new JButton(new DialogAction(frame)));
frame.setVisible(true);
}
// ダイアログを表示するボタン
static class DialogAction extends AbstractAction {
JFrame owner;
public DialogAction(JFrame owner) {
super("ダイアログを出すボタン");
this.owner = owner;
}
@Override
public void actionPerformed(ActionEvent e) {
SampleDialog dlg = new SampleDialog(owner);
dlg.setModal(true);
dlg.setVisible(true);
System.out.println(dlg.isValid());
System.out.println(dlg.isVisible());
}
}
「モーダル(modal)ダイアログ」とは、そのダイアログを開いている間、オーナーの(他の)フレーム(ウィンドウ・ダイアログ)を操作できないダイアログ。
モーダルの反対はモードレス(modeless)。モードレスダイアログは、そのダイアログを開きつつ、他のウィンドウを操作できる。
モーダルダイアログにするには、以下のうちのいずれかの設定を行う。
ダイアログにはオーナーのウィンドウ(フレームやダイアログ)を指定できる。
オーナーを特に指定しない場合は、コンストラクターの引数ownerはnullにしておけばいい。
オーナーの有無は、ダイアログを後ろに隠したり最前面に出したりする際の動作に関わる。
| モーダル | オーナー | ダイアログにフォーカスを与えた時の動作 | オーナーにフォーカスを与えた時の動作 |
|---|---|---|---|
| モーダル | オーナー有り | ダイアログとオーナーが前面に出る。 (最前面はダイアログ) |
ダイアログとオーナーが前面に出る。 (最前面はダイアログ) |
| モーダル | オーナー無し | ダイアログのみが前面に出る。 | ダイアログのみが前面に出る。 (オーナーにはフォーカスが与えられない) |
| モードレス | オーナー有り | ダイアログとオーナーが前面に出る。 (最前面はダイアログ) |
オーナーがアクティブになる。 (ダイアログの陰にはなるが、オーナーを操作可能) |
| モードレス | オーナー無し | ダイアログのみが前面に出る。 | オーナーのみが前面に出る。 |
モーダルダイアログの場合、JDialog#setVisible(true)を呼び出した時点で、処理はダイアログに移る。ダイアログが終了するまでsetVisible()の呼び出しから戻ってこない。
モードレスダイアログの場合、JDialog#setVisible(true)を呼び出してダイアログが表示されたら、すぐに戻ってくる。(並列で処理される)
JFrameと同じく、ダイアログが終了した際の動作をsetDefaultCloseOperation()で設定することが出来る。
ただし、(JFrameでよく使われる)EXIT_ON_CLOSEは指定できない。
| オペレーション | ダイアログ終了時の動作 | 終了後の状態 | |
|---|---|---|---|
| isValid() | isVisible() | ||
| HIDE_ON_CLOSE | 非表示になる。(デフォルト動作) | true | false |
| DISPOSE_ON_CLOSE | 破棄される。 | false | false |
| DO_NOTHING_ON_CLOSE | 何も起きない。(ダイアログが終了できない!) | - | - |
ダイアログ上にJButtonを追加すれば、ボタンを表示できる。[2009-04-06]
これで理屈上はOKボタンもCANCELボタンも作れるわけだが、文言はSwingで共通のものを使いたいのが人情(?)。
以下のようにしてJOptionPaneの文言を取得することが出来る。
import java.util.Locale; import javax.swing.UIManager;
public class SampleDialog extends JDialog {
public SampleDialog(Frame owner) {
super(owner);
setTitle("ボタンの文言の例");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// ボタンを一通り取得してみる例
Locale l = getLocale();
// Locale l = Locale.US;
// Locale l = Locale.JAPANESE;
JPanel panel = new JPanel(new FlowLayout());
panel.add(createButton("ok", l));
panel.add(createButton("cancel", l));
panel.add(createButton("yes", l));
panel.add(createButton("no", l));
// ダイアログに表示するコンポーネントを設定
Container c = getContentPane();
c.add(new JLabel("ボタンの文言の例"), BorderLayout.CENTER);
c.add(panel, BorderLayout.PAGE_END); //ボタンの一覧
pack();
setLocationRelativeTo(null);
}
public static JButton createButton(String key, Locale l) {
String text = UIManager.getString("OptionPane." + key + "ButtonText", l);
JButton button = new JButton(text);
String num = UIManager.getString("OptionPane." + key + "ButtonMnemonic", l);
if (num != null) {
int n = Integer.parseInt(num);
if (n != 0) {
button.setMnemonic(n);
}
}
return button;
}
}
getLocale()で現在のロカールが取得できる。日本の場合はja_JP(Locale.JAPAN)。
これを元にUIManager.get()を使ってJOptionPaneのプロパティーを取得すると、日本語用の文言が取得できる。
試しにLocale.USやLocale.ENGLISHを指定すると、英語の文言が取得できる。
("OptionPane.yesButtonText"や"OptionPane.okButtonText"を使った文言取得は、BasicOptionPaneUI#getButtons()で行われている)
| ロカール | ボタンの文言 | ||||
|---|---|---|---|---|---|
| ok | cancel | yes | no | ||
| Locale.JAPAN Locale.JAPANESE |
ja ja_JP |
了解 | 取消し | はい(Y) | いいえ(N) |
| Locale.ENGLISH Locale.US |
en en_US |
OK | Cancel | Yes | No |
なお、ボタンが押された時のアクションは別途自分で割り当てる必要がある。
普通にOKボタンやCANCELボタンを使いたいなら、JOptionPaneのメッセージにJPanelを割り当てる方法の方が便利かも。