Swing/WindowClosing のバックアップ(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/WindowClosing へ行く。
- 1 (2007-10-08 (月) 16:11:56)
- 2 (2007-10-08 (月) 23:07:09)
- 3 (2008-04-22 (火) 19:05:14)
- 4 (2008-04-22 (火) 21:30:57)
- 5 (2008-04-23 (水) 01:11:16)
- 6 (2008-04-23 (水) 13:21:09)
- 7 (2008-04-23 (水) 15:28:42)
- 8 (2008-04-23 (水) 21:28:02)
- 9 (2008-04-24 (木) 12:31:06)
- 10 (2008-04-26 (土) 00:16:44)
- 11 (2008-05-07 (水) 18:35:31)
- 12 (2008-05-08 (木) 18:57:20)
- 13 (2008-05-09 (金) 12:34:44)
- 14 (2008-05-19 (月) 18:34:50)
- 15 (2008-11-25 (火) 11:25:18)
- 16 (2011-03-04 (金) 14:49:54)
- 17 (2011-03-17 (木) 22:27:27)
- 18 (2012-05-08 (火) 11:24:44)
- 19 (2013-04-11 (木) 21:58:54)
- 20 (2013-07-26 (金) 01:01:21)
- 21 (2014-09-30 (火) 01:16:09)
- 22 (2015-11-05 (木) 03:21:40)
- 23 (2015-12-21 (月) 00:38:59)
- 24 (2016-06-01 (水) 20:48:49)
- 25 (2016-08-12 (金) 15:41:24)
- 26 (2017-09-29 (金) 18:00:48)
- 27 (2018-02-24 (土) 19:46:52)
- 28 (2020-03-03 (火) 18:01:19)
- 29 (2021-08-17 (火) 20:08:30)
- 30 (2024-02-15 (木) 20:17:21)
TITLE:JFrameの終了をキャンセル
JFrameの終了をキャンセル
Posted by terai at 2004-08-09
概要
JFrameを閉じる前に、本当に終了してよいかや、終了をキャンセルするかどうかなどを確認するダイアログを表示します。
- &jnlp;
- &jar;
- &zip;
#screenshot
サンプルコード
public static final String TITLE_CHANGE = "hogehoge";
private final JTextArea textarea = new JTextArea();
private final JButton saveButton = new JButton("Save");
private final JFrame frame;
public MainPanel(final JFrame frame) {
super(new BorderLayout());
this.frame = frame;
final String title = frame.getTitle();
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
if(TITLE_CHANGE.equals(e.getPropertyName())) {
Boolean flg = (Boolean)e.getNewValue();
frame.setTitle(title+(flg?"- [変更]":""));
}
}
});
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
System.out.println("windowClosing");
//タイトルバー右上の×ボタンを押したり、システムメニュー
//(タイトルバー左上クリックなどでポップアップするメニュー)で
//閉じるを選ぶと発生する。
//frame.dispose(); では発生しない。
if(!title.equals(frame.getTitle())) {
java.awt.Toolkit.getDefaultToolkit().beep();
String[] obj = {"テストテキストは変更されています。",
"終了する前に保存しますか?"};
int retValue = JOptionPane.showConfirmDialog(
frame, obj, "テストアプリ", JOptionPane.YES_NO_CANCEL_OPTION);
if(retValue==JOptionPane.YES_OPTION) {
//保存が成功した場合と失敗した場合
//boolean ret = save();
//if(ret) {
//保存が成功したので終了
// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//}else{
//保存に失敗したのでエラーを出してもとに戻る
// frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
// return;
//}
System.out.println("本当はちゃんと保存して終了");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}else if(retValue==JOptionPane.NO_OPTION) {
System.out.println("保存しないで終了");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}else if(retValue==JOptionPane.CANCEL_OPTION) {
System.out.println("終了をキャンセル");
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
}else{
System.out.println("変更されていないのでそのまま終了");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
@Override
public void windowClosed(WindowEvent e) {
//frame.dispose(); で発生。
//このサンプルではwebstart用にEXIT_ON_CLOSEを使っているので、
//タイトルバー右上の×ボタンクリックでは呼ばれないはず。
System.out.println("windowClosed");
//When DISPOSE_ON_CLOSE met WebStart > www.pushing-pixels.org/?p=232
//通常(webstartを気にしなくてもよい場合)なら、
//setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//を使えば、タイトルバー右上の×ボタンクリックでも
//windowClosingの後に、windowClosedが発生する。
}
});
textarea.setText("Test Test Test");
textarea.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
fireTitleChangeEvent(true);
}
public void removeUpdate(DocumentEvent e) {
fireTitleChangeEvent(true);
}
public void changedUpdate(DocumentEvent e) {}
});
saveButton.setEnabled(false);
saveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("ダミーなので保存はしない");
fireTitleChangeEvent(false);
}
});
add(new JScrollPane(textarea));
add(saveButton, BorderLayout.SOUTH);
setPreferredSize(new Dimension(512, 320));
}
private void fireTitleChangeEvent(boolean toggle) {
if(toggle) {
saveButton.setEnabled(true);
firePropertyChange(TITLE_CHANGE, Boolean.FALSE, Boolean.TRUE);
}else{
saveButton.setEnabled(false);
firePropertyChange(TITLE_CHANGE, Boolean.TRUE, Boolean.FALSE);
}
}
解説
上記のサンプルでは、JFrameを閉じるようとしたとき*1に、内部のテキストが変更されている場合は、「終了する前に保存しますか?」と確認ダイアログを表示するようになっています。
- はい
- 実際に使用する場合は、ここで変更されたテキストを保存するような処理を実装します。
- 上記のサンプルではなにもしないで、WindowConstants.EXIT_ON_CLOSE を JFrame#setDefaultCloseOperation(int)メソッドで設定して、JFrameを終了しています。
- いいえ
- WindowConstants.EXIT_ON_CLOSE を JFrame#setDefaultCloseOperation(int)メソッドで設定して、JFrameを終了しています。
- 取り消し
- WindowConstants.DO_NOTHING_ON_CLOSE を JFrame#setDefaultCloseOperation(int)メソッドで設定して、終了をキャンセルしています。
テキストが変更されているかどうかは、タイトルの文字列をフラグにして判断できるようになっています。
- ドキュメントに文字列が追加されたとき、ソース側からfirePropertyChangeなどで、リスナーに変更をイベントで報告
- リスナー側ではこのイベントを受け、JFrameのタイトルを変更