Zdarzyło się kilka razy, że potrzebowałem takiej właśnie funkcjonalności. Niestety, nie znalazłem nigdzie żadnego sensownego gotowca, więc ostatecznie sam napisałem taką oto prostą klasę narzędziową. Jest ona zależna od biblioteki commons-lang, jednak przy odrobinie chęci można się tejże zależności bez problemu pozbyć.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
 *  SwingUtilities.java
 *
 *  Copyright (C) 2009  Kamil Dybicz
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 3 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */
package net.javaio.swing;

import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import org.apache.commons.lang.RandomStringUtils;

/**
 *
 * @author Kamil Dybicz
 */
public class SwingUtilities {

    /**
     * This method is used to install {@link WindowClosingAction} that will be
     * fired after pressing Escape key by user but only when this frame will be
     * focused window.
     *
     * @param dialog
     */
    public static void installWindowClosingActionOnEscapeKey(JFrame frame) {
        if (frame == null) {
            return;
        }

        String actionName = "WindowClosingAction-" + RandomStringUtils.randomAlphanumeric(10);
        frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), actionName);
        frame.getRootPane().getActionMap().put(actionName, new WindowClosingAction(frame));
    }

    /**
     * This method is used to install {@link WindowClosingAction} that will be
     * fired after pressing Escape key by user but only when this dialog will be
     * focused window.
     *
     * @param dialog
     */
    public static void installWindowClosingActionOnEscapeKey(JDialog dialog) {
        if (dialog == null) {
            return;
        }

        String actionName = "WindowClosingAction-" + RandomStringUtils.randomAlphanumeric(10);
        dialog.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), actionName);
        dialog.getRootPane().getActionMap().put(actionName, new WindowClosingAction(dialog));
    }

    /**
     * This method is posting Window Closing Event to System Event Queue if
     * {@link Window} is not-null, if else do nothing.
     *
     * @param window
     */
    public static void fireWindowClosingEvent(Window window) {
        if (window == null) {
            return;
        }

        window.getToolkit().getSystemEventQueue().postEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
    }

    /**
     * This class represent an action, that could be used to close {@link Window}
     * using {@link #fireWindowClosingEvent(java.awt.Window)}.
     */
    public static class WindowClosingAction extends AbstractAction {

        private static final long serialVersionUID = 1066322459108218644L;
        private final Window window;

        private WindowClosingAction() {
            this.window = null;
        }

        public WindowClosingAction(Window window) {
            this.window = window;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            fireWindowClosingEvent(window);
        }
    }
}