web-dev-qa-db-ja.com

Swing:ESCキーが押されたときにダイアログを閉じる方法

SwingによるGUI開発。

アプリケーションで開くファイルを選択するためのカスタムダイアログがあります。そのクラスはjavax.swing.JDialogには、他のコンポーネントの中でも特にJFileChooserが含まれており、表示と非表示を切り替えることができます。

JFileChooserコンポーネントは既にESCキーを単独で処理します。ファイル選択が表示され(ダイアログに埋め込まれている)、ESCを押すと、ファイル選択は自動的に非表示になります。

ここで、ダイアログで同じことを行いたいと思います。ESCを押すと、ダイアログを閉じます。埋め込みファイルチューザーが表示されている場合、ESCキーはそれを非表示にするだけです。

何か案は ?

59
Leonel

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 
    ); 
}
59

次のスニペットを使用できます。 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);

}
63
Ayman

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);
13
Java42

私は両方のトップアンサーの実装に問題がありました。 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);

参照資料

4
skia.heliou

__コード__ 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); 
2
Wesos de Queso