SwingによるGUI開発。
アプリケーションで開くファイルを選択するためのカスタムダイアログがあります。そのクラスはjavax.swing.JDialog
には、他のコンポーネントの中でも特にJFileChooser
が含まれており、表示と非表示を切り替えることができます。
JFileChooser
コンポーネントは既にESCキーを単独で処理します。ファイル選択が表示され(ダイアログに埋め込まれている)、ESCを押すと、ファイル選択は自動的に非表示になります。
ここで、ダイアログで同じことを行いたいと思います。ESCを押すと、ダイアログを閉じます。埋め込みファイルチューザーが表示されている場合、ESCキーはそれを非表示にするだけです。
何か案は ?
Swingの主要なアクションを処理するには、InputMap
およびActionMap
を使用します。ダイアログをきれいに閉じるには、ウィンドウを閉じるイベントを送信します。
私の ウェブログ から:
private static final KeyStroke escapeStroke =
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
public static final String dispatchWindowClosingActionMapKey =
"com.spodding.tackline.dispatch:WINDOW_CLOSING";
public static void installEscapeCloseOperation(final JDialog dialog) {
Action dispatchClosing = new AbstractAction() {
public void actionPerformed(ActionEvent event) {
dialog.dispatchEvent(new WindowEvent(
dialog, WindowEvent.WINDOW_CLOSING
));
}
};
JRootPane root = dialog.getRootPane();
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
escapeStroke, dispatchWindowClosingActionMapKey
);
root.getActionMap().put( dispatchWindowClosingActionMapKey, dispatchClosing
);
}
次のスニペットを使用できます。 rootPaneはダイアログ内の任意のコンポーネントからイベントを取得するため、これは優れています。必要に応じて、setVisible(false)をdispose()に置き換えることができます。
public static void addEscapeListener(final JDialog dialog) {
ActionListener escListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
};
dialog.getRootPane().registerKeyboardAction(escListener,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
Java 8の新しい機能を使用する手法を探している場合は、ラムダ式を試してください。
dialog.getRootPane().registerKeyboardAction(e -> {
window.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
または
KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
int w = JComponent.WHEN_IN_FOCUSED_WINDOW;
dialog.getRootPane().registerKeyboardAction(e -> window.dispose(), k, w);
私は両方のトップアンサーの実装に問題がありました。 AbstractAction
を使用してテキストベースのフィールド内で機能するほとんどのAction
のメソッドを自動実装する、かなりコンパクトなバージョンを以下に示します(@pratikabuのリクエストによる)。
final AbstractAction escapeAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent ae) {
dispose();
}
};
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE_KEY");
getRootPane().getActionMap().put("ESCAPE_KEY", escapeAction);
__コード__ CtrlW
Action closeAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
dispose();
}
};
KeyStroke esc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(esc, "closex");
getRootPane().getActionMap().put("closex", closeAction);
KeyStroke ctrlW = KeyStroke.getKeyStroke("control W");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlW, "close");
getRootPane().getActionMap().put("close", closeAction);