-
Notifications
You must be signed in to change notification settings - Fork 3
/
EscapeAction.java
108 lines (88 loc) · 2.97 KB
/
EscapeAction.java
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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* Convenience Action to dispose of a Swing Window by using the Escape key.
* Before disposing of the window the Action will first attempt to hide
* any popups. In this case the user will need to invoke the Escape key a
* second time before the Window is disposed.
*/
public class EscapeAction extends AbstractAction
{
private static final String KEY_STROKE_AND_KEY = "ESCAPE";
private static final KeyStroke ESCAPE_KEY_STROKE = KeyStroke.getKeyStroke( KEY_STROKE_AND_KEY );
public EscapeAction()
{
super("Escape");
}
/**
* Implement the Escape Action. First attempt to hide a popup menu.
* If no popups are found then dispose the window.
*/
@Override
public void actionPerformed(ActionEvent e)
{
// When a popup is visible the root pane of the Window will
// (generally) have focus
Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
JComponent rootPane = (JComponent)component;
// In some cases a component added to a popup menu may have focus, but
// we need the root pane to check for popup menu key bindings
if ( ! (rootPane instanceof JRootPane) )
{
rootPane = (JComponent)SwingUtilities.getAncestorOfClass(JRootPane.class, component);
}
// Hide the popup menu when an ESCAPE key binding is found,
// otherwise dispose the Window
ActionListener escapeAction = getEscapeAction( rootPane );
if (escapeAction != null)
{
escapeAction.actionPerformed(null);
}
else
{
Window window = SwingUtilities.windowForComponent(component);
window.dispose();
}
}
private ActionListener getEscapeAction(JComponent rootPane)
{
// Search the parent InputMap to see if a binding for the ESCAPE key
// exists. This binding is added when a popup menu is made visible
// (and removed when the popup menu is hidden).
InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
if (im == null) return null;
im = im.getParent();
if (im == null) return null;
Object[] keys = im.keys();
if (keys == null) return null;
for (Object keyStroke: keys)
{
if (keyStroke.equals(ESCAPE_KEY_STROKE))
{
Object key = im.get(ESCAPE_KEY_STROKE);
return rootPane.getActionMap().get( key );
}
}
return null;
}
/**
* Convenience method for JDialogs to register the EscapeAction
*
* ¶m dialog the JDialog the EscapeAction is registered with
*/
public void register(JDialog dialog)
{
register( dialog.getRootPane() );
}
/**
* Register the EscapeAction on the specified JRootPane
*
* ¶m rootPane the JRootPane the EscapeAction is registered with
*/
public void register(JRootPane rootPane)
{
rootPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(ESCAPE_KEY_STROKE, KEY_STROKE_AND_KEY);
rootPane.getActionMap().put(KEY_STROKE_AND_KEY, this);
}
}