1 /*
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 package javax.swing;
26
27 import java.awt.AWTKeyStroke;
28 import java.awt.event.KeyEvent;
29
30 /**
31 * A KeyStroke represents a key action on the keyboard, or equivalent input
32 * device. KeyStrokes can correspond to only a press or release of a particular
33 * key, just as KEY_PRESSED and KEY_RELEASED KeyEvents do; alternately, they
34 * can correspond to typing a specific Java character, just as KEY_TYPED
35 * KeyEvents do. In all cases, KeyStrokes can specify modifiers (alt, shift,
36 * control, meta, altGraph, or a combination thereof) which must be present during the
37 * action for an exact match.
38 * <p>
39 * KeyStrokes are used to define high-level (semantic) action events. Instead
40 * of trapping every keystroke and throwing away the ones you are not
41 * interested in, those keystrokes you care about automatically initiate
42 * actions on the Components with which they are registered.
43 * <p>
44 * KeyStrokes are immutable, and are intended to be unique. Client code cannot
45 * create a KeyStroke; a variant of <code>getKeyStroke</code> must be used
46 * instead. These factory methods allow the KeyStroke implementation to cache
47 * and share instances efficiently.
48 * <p>
49 * <strong>Warning:</strong>
50 * Serialized objects of this class will not be compatible with
51 * future Swing releases. The current serialization support is
52 * appropriate for short term storage or RMI between applications running
53 * the same version of Swing. As of 1.4, support for long term storage
54 * of all JavaBeans<sup><font size="-2">TM</font></sup>
55 * has been added to the <code>java.beans</code> package.
56 * Please see {@link java.beans.XMLEncoder}.
57 *
58 * @see javax.swing.text.Keymap
59 * @see #getKeyStroke
60 *
61 * @author Arnaud Weber
62 * @author David Mendenhall
63 */
64 public class KeyStroke extends AWTKeyStroke {
65
66 /**
67 * Serial Version ID.
68 */
69 private static final long serialVersionUID = -9060180771037902530L;
70
71 private KeyStroke() {
72 }
73 private KeyStroke(char keyChar, int keyCode, int modifiers,
74 boolean onKeyRelease) {
75 super(keyChar, keyCode, modifiers, onKeyRelease);
76 }
77
78 /**
79 * Returns a shared instance of a <code>KeyStroke</code>
80 * that represents a <code>KEY_TYPED</code> event for the
81 * specified character.
82 *
83 * @param keyChar the character value for a keyboard key
84 * @return a KeyStroke object for that key
85 */
86 public static KeyStroke getKeyStroke(char keyChar) {
87 synchronized (AWTKeyStroke.class) {
88 registerSubclass(KeyStroke.class);
89 return (KeyStroke)getAWTKeyStroke(keyChar);
90 }
91 }
92
93 /**
94 * Returns an instance of a KeyStroke, specifying whether the key is
95 * considered to be activated when it is pressed or released. Unlike all
96 * other factory methods in this class, the instances returned by this
97 * method are not necessarily cached or shared.
98 *
99 * @param keyChar the character value for a keyboard key
100 * @param onKeyRelease <code>true</code> if this KeyStroke corresponds to a
101 * key release; <code>false</code> otherwise.
102 * @return a KeyStroke object for that key
103 * @deprecated use getKeyStroke(char)
104 */
105 @Deprecated
106 public static KeyStroke getKeyStroke(char keyChar, boolean onKeyRelease) {
107 return new KeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, onKeyRelease);
108 }
109
110 /**
111 * Returns a shared instance of a {@code KeyStroke}
112 * that represents a {@code KEY_TYPED} event for the
113 * specified Character object and a
114 * set of modifiers. Note that the first parameter is of type Character
115 * rather than char. This is to avoid inadvertent clashes with calls to
116 * <code>getKeyStroke(int keyCode, int modifiers)</code>.
117 *
118 * The modifiers consist of any combination of following:<ul>
119 * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
120 * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
121 * <li>java.awt.event.InputEvent.META_DOWN_MASK
122 * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
123 * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
124 * </ul>
125 * The old modifiers listed below also can be used, but they are
126 * mapped to _DOWN_ modifiers. <ul>
127 * <li>java.awt.event.InputEvent.SHIFT_MASK
128 * <li>java.awt.event.InputEvent.CTRL_MASK
129 * <li>java.awt.event.InputEvent.META_MASK
130 * <li>java.awt.event.InputEvent.ALT_MASK
131 * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
132 * </ul>
133 * also can be used, but they are mapped to _DOWN_ modifiers.
134 *
135 * Since these numbers are all different powers of two, any combination of
136 * them is an integer in which each bit represents a different modifier
137 * key. Use 0 to specify no modifiers.
138 *
139 * @param keyChar the Character object for a keyboard character
140 * @param modifiers a bitwise-ored combination of any modifiers
141 * @return an KeyStroke object for that key
142 * @throws IllegalArgumentException if keyChar is null
143 *
144 * @see java.awt.event.InputEvent
145 * @since 1.3
146 */
147 public static KeyStroke getKeyStroke(Character keyChar, int modifiers) {
148 synchronized (AWTKeyStroke.class) {
149 registerSubclass(KeyStroke.class);
150 return (KeyStroke)getAWTKeyStroke(keyChar, modifiers);
151 }
152 }
153
154 /**
155 * Returns a shared instance of a KeyStroke, given a numeric key code and a
156 * set of modifiers, specifying whether the key is activated when it is
157 * pressed or released.
158 * <p>
159 * The "virtual key" constants defined in java.awt.event.KeyEvent can be
160 * used to specify the key code. For example:<ul>
161 * <li>java.awt.event.KeyEvent.VK_ENTER
162 * <li>java.awt.event.KeyEvent.VK_TAB
163 * <li>java.awt.event.KeyEvent.VK_SPACE
164 * </ul>
165 * The modifiers consist of any combination of:<ul>
166 * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
167 * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
168 * <li>java.awt.event.InputEvent.META_DOWN_MASK
169 * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
170 * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
171 * </ul>
172 * The old modifiers <ul>
173 * <li>java.awt.event.InputEvent.SHIFT_MASK
174 * <li>java.awt.event.InputEvent.CTRL_MASK
175 * <li>java.awt.event.InputEvent.META_MASK
176 * <li>java.awt.event.InputEvent.ALT_MASK
177 * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
178 * </ul>
179 * also can be used, but they are mapped to _DOWN_ modifiers.
180 *
181 * Since these numbers are all different powers of two, any combination of
182 * them is an integer in which each bit represents a different modifier
183 * key. Use 0 to specify no modifiers.
184 *
185 * @param keyCode an int specifying the numeric code for a keyboard key
186 * @param modifiers a bitwise-ored combination of any modifiers
187 * @param onKeyRelease <code>true</code> if the KeyStroke should represent
188 * a key release; <code>false</code> otherwise.
189 * @return a KeyStroke object for that key
190 *
191 * @see java.awt.event.KeyEvent
192 * @see java.awt.event.InputEvent
193 */
194 public static KeyStroke getKeyStroke(int keyCode, int modifiers,
195 boolean onKeyRelease) {
196 synchronized (AWTKeyStroke.class) {
197 registerSubclass(KeyStroke.class);
198 return (KeyStroke)getAWTKeyStroke(keyCode, modifiers,
199 onKeyRelease);
200 }
201 }
202
203 /**
204 * Returns a shared instance of a KeyStroke, given a numeric key code and a
205 * set of modifiers. The returned KeyStroke will correspond to a key press.
206 * <p>
207 * The "virtual key" constants defined in java.awt.event.KeyEvent can be
208 * used to specify the key code. For example:<ul>
209 * <li>java.awt.event.KeyEvent.VK_ENTER
210 * <li>java.awt.event.KeyEvent.VK_TAB
211 * <li>java.awt.event.KeyEvent.VK_SPACE
212 * </ul>
213 * The modifiers consist of any combination of:<ul>
214 * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
215 * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
216 * <li>java.awt.event.InputEvent.META_DOWN_MASK
217 * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
218 * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
219 * </ul>
220 * The old modifiers <ul>
221 * <li>java.awt.event.InputEvent.SHIFT_MASK
222 * <li>java.awt.event.InputEvent.CTRL_MASK
223 * <li>java.awt.event.InputEvent.META_MASK
224 * <li>java.awt.event.InputEvent.ALT_MASK
225 * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
226 * </ul>
227 * also can be used, but they are mapped to _DOWN_ modifiers.
228 *
229 * Since these numbers are all different powers of two, any combination of
230 * them is an integer in which each bit represents a different modifier
231 * key. Use 0 to specify no modifiers.
232 *
233 * @param keyCode an int specifying the numeric code for a keyboard key
234 * @param modifiers a bitwise-ored combination of any modifiers
235 * @return a KeyStroke object for that key
236 *
237 * @see java.awt.event.KeyEvent
238 * @see java.awt.event.InputEvent
239 */
240 public static KeyStroke getKeyStroke(int keyCode, int modifiers) {
241 synchronized (AWTKeyStroke.class) {
242 registerSubclass(KeyStroke.class);
243 return (KeyStroke)getAWTKeyStroke(keyCode, modifiers);
244 }
245 }
246
247 /**
248 * Returns a KeyStroke which represents the stroke which generated a given
249 * KeyEvent.
250 * <p>
251 * This method obtains the keyChar from a KeyTyped event, and the keyCode
252 * from a KeyPressed or KeyReleased event. The KeyEvent modifiers are
253 * obtained for all three types of KeyEvent.
254 *
255 * @param anEvent the KeyEvent from which to obtain the KeyStroke
256 * @throws NullPointerException if <code>anEvent</code> is null
257 * @return the KeyStroke that precipitated the event
258 */
259 public static KeyStroke getKeyStrokeForEvent(KeyEvent anEvent) {
260 synchronized (AWTKeyStroke.class) {
261 registerSubclass(KeyStroke.class);
262 return (KeyStroke)getAWTKeyStrokeForEvent(anEvent);
263 }
264 }
265
266 /**
267 * Parses a string and returns a <code>KeyStroke</code>.
268 * The string must have the following syntax:
269 * <pre>
270 * <modifiers>* (<typedID> | <pressedReleasedID>)
271 *
272 * modifiers := shift | control | ctrl | meta | alt | altGraph
273 * typedID := typed <typedKey>
274 * typedKey := string of length 1 giving Unicode character.
275 * pressedReleasedID := (pressed | released) key
276 * key := KeyEvent key code name, i.e. the name following "VK_".
277 * </pre>
278 * If typed, pressed or released is not specified, pressed is assumed. Here
279 * are some examples:
280 * <pre>
281 * "INSERT" => getKeyStroke(KeyEvent.VK_INSERT, 0);
282 * "control DELETE" => getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
283 * "alt shift X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
284 * "alt shift released X" => getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
285 * "typed a" => getKeyStroke('a');
286 * </pre>
287 *
288 * In order to maintain backward-compatibility, specifying a null String,
289 * or a String which is formatted incorrectly, returns null.
290 *
291 * @param s a String formatted as described above
292 * @return a KeyStroke object for that String, or null if the specified
293 * String is null, or is formatted incorrectly
294 *
295 * @see java.awt.event.KeyEvent
296 */
297 public static KeyStroke getKeyStroke(String s) {
298 if (s == null || s.length() == 0) {
299 return null;
300 }
301 synchronized (AWTKeyStroke.class) {
302 registerSubclass(KeyStroke.class);
303 try {
304 return (KeyStroke)getAWTKeyStroke(s);
305 } catch (IllegalArgumentException e) {
306 return null;
307 }
308 }
309 }
310 }