View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * 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&trade;
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      * Alternatively, the key code may be obtained by calling
166      * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
167      *
168      * The modifiers consist of any combination of:<ul>
169      * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
170      * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
171      * <li>java.awt.event.InputEvent.META_DOWN_MASK
172      * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
173      * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
174      * </ul>
175      * The old modifiers <ul>
176      * <li>java.awt.event.InputEvent.SHIFT_MASK
177      * <li>java.awt.event.InputEvent.CTRL_MASK
178      * <li>java.awt.event.InputEvent.META_MASK
179      * <li>java.awt.event.InputEvent.ALT_MASK
180      * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
181      * </ul>
182      * also can be used, but they are mapped to _DOWN_ modifiers.
183      *
184      * Since these numbers are all different powers of two, any combination of
185      * them is an integer in which each bit represents a different modifier
186      * key. Use 0 to specify no modifiers.
187      *
188      * @param keyCode an int specifying the numeric code for a keyboard key
189      * @param modifiers a bitwise-ored combination of any modifiers
190      * @param onKeyRelease <code>true</code> if the KeyStroke should represent
191      *        a key release; <code>false</code> otherwise.
192      * @return a KeyStroke object for that key
193      *
194      * @see java.awt.event.KeyEvent
195      * @see java.awt.event.InputEvent
196      */
197     public static KeyStroke getKeyStroke(int keyCode, int modifiers,
198                                          boolean onKeyRelease) {
199         synchronized (AWTKeyStroke.class) {
200             registerSubclass(KeyStroke.class);
201             return (KeyStroke)getAWTKeyStroke(keyCode, modifiers,
202                                               onKeyRelease);
203         }
204     }
205 
206     /**
207      * Returns a shared instance of a KeyStroke, given a numeric key code and a
208      * set of modifiers. The returned KeyStroke will correspond to a key press.
209      * <p>
210      * The "virtual key" constants defined in java.awt.event.KeyEvent can be
211      * used to specify the key code. For example:<ul>
212      * <li>java.awt.event.KeyEvent.VK_ENTER
213      * <li>java.awt.event.KeyEvent.VK_TAB
214      * <li>java.awt.event.KeyEvent.VK_SPACE
215      * </ul>
216      * Alternatively, the key code may be obtained by calling
217      * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
218      *
219      * The modifiers consist of any combination of:<ul>
220      * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
221      * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
222      * <li>java.awt.event.InputEvent.META_DOWN_MASK
223      * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
224      * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
225      * </ul>
226      * The old modifiers <ul>
227      * <li>java.awt.event.InputEvent.SHIFT_MASK
228      * <li>java.awt.event.InputEvent.CTRL_MASK
229      * <li>java.awt.event.InputEvent.META_MASK
230      * <li>java.awt.event.InputEvent.ALT_MASK
231      * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
232      * </ul>
233      * also can be used, but they are mapped to _DOWN_ modifiers.
234      *
235      * Since these numbers are all different powers of two, any combination of
236      * them is an integer in which each bit represents a different modifier
237      * key. Use 0 to specify no modifiers.
238      *
239      * @param keyCode an int specifying the numeric code for a keyboard key
240      * @param modifiers a bitwise-ored combination of any modifiers
241      * @return a KeyStroke object for that key
242      *
243      * @see java.awt.event.KeyEvent
244      * @see java.awt.event.InputEvent
245      */
246     public static KeyStroke getKeyStroke(int keyCode, int modifiers) {
247         synchronized (AWTKeyStroke.class) {
248             registerSubclass(KeyStroke.class);
249             return (KeyStroke)getAWTKeyStroke(keyCode, modifiers);
250         }
251     }
252 
253     /**
254      * Returns a KeyStroke which represents the stroke which generated a given
255      * KeyEvent.
256      * <p>
257      * This method obtains the keyChar from a KeyTyped event, and the keyCode
258      * from a KeyPressed or KeyReleased event. The KeyEvent modifiers are
259      * obtained for all three types of KeyEvent.
260      *
261      * @param anEvent the KeyEvent from which to obtain the KeyStroke
262      * @throws NullPointerException if <code>anEvent</code> is null
263      * @return the KeyStroke that precipitated the event
264      */
265     public static KeyStroke getKeyStrokeForEvent(KeyEvent anEvent) {
266         synchronized (AWTKeyStroke.class) {
267             registerSubclass(KeyStroke.class);
268             return (KeyStroke)getAWTKeyStrokeForEvent(anEvent);
269         }
270     }
271 
272     /**
273      * Parses a string and returns a <code>KeyStroke</code>.
274      * The string must have the following syntax:
275      * <pre>
276      *    &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
277      *
278      *    modifiers := shift | control | ctrl | meta | alt | altGraph
279      *    typedID := typed &lt;typedKey&gt;
280      *    typedKey := string of length 1 giving Unicode character.
281      *    pressedReleasedID := (pressed | released) key
282      *    key := KeyEvent key code name, i.e. the name following "VK_".
283      * </pre>
284      * If typed, pressed or released is not specified, pressed is assumed. Here
285      * are some examples:
286      * <pre>
287      *     "INSERT" =&gt; getKeyStroke(KeyEvent.VK_INSERT, 0);
288      *     "control DELETE" =&gt; getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
289      *     "alt shift X" =&gt; getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
290      *     "alt shift released X" =&gt; getKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
291      *     "typed a" =&gt; getKeyStroke('a');
292      * </pre>
293      *
294      * In order to maintain backward-compatibility, specifying a null String,
295      * or a String which is formatted incorrectly, returns null.
296      *
297      * @param s a String formatted as described above
298      * @return a KeyStroke object for that String, or null if the specified
299      *         String is null, or is formatted incorrectly
300      *
301      * @see java.awt.event.KeyEvent
302      */
303     public static KeyStroke getKeyStroke(String s) {
304         if (s == null || s.length() == 0) {
305             return null;
306         }
307         synchronized (AWTKeyStroke.class) {
308             registerSubclass(KeyStroke.class);
309             try {
310                 return (KeyStroke)getAWTKeyStroke(s);
311             } catch (IllegalArgumentException e) {
312                 return null;
313             }
314         }
315     }
316 }