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