1 /*
   2  * Copyright (c) 1997, 2009, 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 }