Java Swing –ダイアログウィンドウを上に保つ
アプリケーションにダイアログを実装する最も一般的な(and simple)の方法は、JOptionPane
クラスです。 この記事では、ユーザーがJOptionPane
で作成されたボタンをクリックしたときにダイアログウィンドウを閉じるJOptionPane
のデフォルトの動作を「上書き」する方法について説明します。
例に進む前に知っておく必要があるのは、アプリケーションでJOptionPane
を使用する場合、実際に舞台裏で実行されるのはモーダルJDialog
であるということです。 JOptionPane
は、JDialog
を自動的に作成し、それ自体をcontent pane
に追加するコンテナです。
1. 基本的な例
この例では、ダイアログウィンドウが自動的に閉じるのを停止し、代わりにPropertyChange
リスナーを実装して独自に処理します。 次の例は、ユーザーインタラクションや入力チェックの処理がないため、コードにこのメカニズムを実装する絶対的な基盤です。
KeepDialogUp.java
package com.techfou.stayup; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; public class KeepDialogUp { public static void main(String[] args) { JFrame frame = new JFrame(); ImageIcon icon = new ImageIcon("src/images/turtle64.png"); Object[] options = {"I DO LOVE TURTLES"}; JOptionPane jop = new JOptionPane("Admit your love for turtles\nor you shall not pass!!" , JOptionPane.ERROR_MESSAGE, 0, icon, options, options[0]); JDialog dialog = new JDialog(frame, "You LOVE turtles", true); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setContentPane(jop); jop.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (JOptionPane.VALUE_PROPERTY.equals(evt.getPropertyName())) { dialog.dispose(); JOptionPane.showMessageDialog(null, "Good for you >:P"); System.exit(0); } } }); dialog.pack(); dialog.setLocationRelativeTo(frame); dialog.setVisible(true); } }
出力:
ユーザーがウィンドウを閉じようとしても、何も起こりません。 ユーザーが「I DO LOVE TURTLES」ボタンをクリックすると、プログラムは次のダイアログを表示して終了します。
2. リスナーを使用した例
さて、前の例をスパイスアップしましょう。 ユーザーがダイアログを閉じようとする試みを処理するためにwindowListener
を追加し、propertyChangeListener
でのユーザーの入力を確認します。
KeepDialogUpExtended.java
package com.techfou.stayup; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; public class KeepDialogUpExtended { public static void main(String[] args) { JFrame frame = new JFrame(); ImageIcon icon = new ImageIcon("src/images/turtle64.png"); Object[] options = {"I DO LOVE TURTLES"}; JOptionPane jop = new JOptionPane("Admit your love for turtles\nor you shall not pass!!", JOptionPane.ERROR_MESSAGE, 0, icon, options, options[0]); JDialog dialog = new JDialog(frame, "You LOVE turtles", true); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setContentPane(jop); dialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { JOptionPane.showMessageDialog(frame, "YOU SHALL NOT PASS", "!!", JOptionPane.ERROR_MESSAGE); } }); jop.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (JOptionPane.VALUE_PROPERTY.equals(evt.getPropertyName())) { if (jop.getValue().equals(options[0])) { dialog.dispose(); JOptionPane.showMessageDialog(null, "Good for you >:P"); System.exit(0); } else { JOptionPane.showMessageDialog(frame, "There is no\n>> ESC <<", "You little shenanigan...", JOptionPane.ERROR_MESSAGE); } } } }); dialog.pack(); dialog.setLocationRelativeTo(frame); dialog.setVisible(true); } }
出力:
ユーザーがウィンドウを閉じようとした場合:
ユーザーがEscボタンを押した場合:
これは、このメカニズムをほぼまとめたものです。 JOptionPane
の戻り値をチェックする従来の方法でユーザー入力を処理する方が、リソースの効率が高いと主張する人もいるかもしれません。 多分そうでないかもしれません。コードの残りの部分によっては、このメカニックが欠落している可能性があります。 確かなことは、あなたが知っているほど正しい選択をする可能性が高くなるということです。