jdk/src/share/classes/java/awt/AWTKeyStroke.java
author tbell
Wed, 07 Oct 2009 14:15:01 -0700
changeset 3965 63aae8ce7f47
parent 2473 3f4bbd3be2f1
child 5506 202f599c92aa
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
2473
3f4bbd3be2f1 6680988: KeyEvent is still missing VK values for many keyboards
yan
parents: 2
diff changeset
     2
 * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
package java.awt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
import java.awt.event.KeyEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.event.InputEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.Collections;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.StringTokenizer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.lang.reflect.Constructor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.lang.reflect.InvocationTargetException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.lang.reflect.Modifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.lang.reflect.Field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * An <code>AWTKeyStroke</code> represents a key action on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * keyboard, or equivalent input device. <code>AWTKeyStroke</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * can correspond to only a press or release of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * particular key, just as <code>KEY_PRESSED</code> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * <code>KEY_RELEASED</code> <code>KeyEvent</code>s do;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * alternately, they can correspond to typing a specific Java character, just
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * as <code>KEY_TYPED</code> <code>KeyEvent</code>s do.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * In all cases, <code>AWTKeyStroke</code>s can specify modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * (alt, shift, control, meta, altGraph, or a combination thereof) which must be present
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * during the action for an exact match.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * <code>AWTKeyStrokes</code> are immutable, and are intended
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * to be unique. Client code should never create an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <code>AWTKeyStroke</code> on its own, but should instead use
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * a variant of <code>getAWTKeyStroke</code>. Client use of these factory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * methods allows the <code>AWTKeyStroke</code> implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * to cache and share instances efficiently.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * @see #getAWTKeyStroke
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * @author Arnaud Weber
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * @author David Mendenhall
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
public class AWTKeyStroke implements Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    static final long serialVersionUID = -6430539691155161871L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    private static Map cache;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private static AWTKeyStroke cacheKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    private static Constructor ctor = getCtor(AWTKeyStroke.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    private static Map modifierKeywords;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     * Associates VK_XXX (as a String) with code (as Integer). This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     * done to avoid the overhead of the reflective call to find the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     * constant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private static VKCollection vks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    private char keyChar = KeyEvent.CHAR_UNDEFINED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private int keyCode = KeyEvent.VK_UNDEFINED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private int modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private boolean onKeyRelease;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        /* ensure that the necessary native libraries are loaded */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        Toolkit.loadLibraries();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * Constructs an <code>AWTKeyStroke</code> with default values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * The default values used are:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * <table border="1" summary="AWTKeyStroke default values">
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * <tr><th>Property</th><th>Default Value</th></tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     *    <td>Key Char</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     *    <td><code>KeyEvent.CHAR_UNDEFINED</code></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     *    <td>Key Code</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     *    <td><code>KeyEvent.VK_UNDEFINED</code></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     *    <td>Modifiers</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     *    <td>none</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     *    <td>On key release?</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     *    <td><code>false</code></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * <code>AWTKeyStroke</code>s should not be constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * by client code. Use a variant of <code>getAWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * @see #getAWTKeyStroke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    protected AWTKeyStroke() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * Constructs an <code>AWTKeyStroke</code> with the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * values. <code>AWTKeyStroke</code>s should not be constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * by client code. Use a variant of <code>getAWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * @param keyChar the character value for a keyboard key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * @param keyCode the key code for this <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * @param modifiers a bitwise-ored combination of any modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * @param onKeyRelease <code>true</code> if this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     *        <code>AWTKeyStroke</code> corresponds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     *        to a key release; <code>false</code> otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * @see #getAWTKeyStroke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                           boolean onKeyRelease) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        this.keyChar = keyChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        this.keyCode = keyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        this.modifiers = modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        this.onKeyRelease = onKeyRelease;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * Registers a new class which the factory methods in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * <code>AWTKeyStroke</code> will use when generating new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * instances of <code>AWTKeyStroke</code>s. After invoking this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * method, the factory methods will return instances of the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * Class. The specified Class must be either <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * or derived from <code>AWTKeyStroke</code>, and it must have a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * no-arg constructor. The constructor can be of any accessibility,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * including <code>private</code>. This operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * flushes the current <code>AWTKeyStroke</code> cache.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * @param subclass the new Class of which the factory methods should create
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     *        instances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * @throws IllegalArgumentException if subclass is <code>null</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     *         or if subclass does not have a no-arg constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * @throws ClassCastException if subclass is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     *         <code>AWTKeyStroke</code>, or a class derived from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     *         <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    protected static void registerSubclass(Class<?> subclass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (subclass == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            throw new IllegalArgumentException("subclass cannot be null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            // Already registered
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            throw new ClassCastException("subclass is not derived from AWTKeyStroke");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        Constructor ctor = getCtor(subclass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        String couldNotInstantiate = "subclass could not be instantiated";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        if (ctor == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            AWTKeyStroke stroke = (AWTKeyStroke)ctor.newInstance((Object[]) null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            if (stroke == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        } catch (NoSuchMethodError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        } catch (ExceptionInInitializerError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        } catch (InstantiationException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        } catch (IllegalAccessException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        } catch (InvocationTargetException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            throw new IllegalArgumentException(couldNotInstantiate);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        synchronized (AWTKeyStroke.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            AWTKeyStroke.ctor = ctor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            cache = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            cacheKey = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /* returns noarg Constructor for class with accessible flag. No security
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
       threat as accessible flag is set only for this Constructor object,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
       not for Class constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    private static Constructor getCtor(final Class clazz)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        Object ctor = AccessController.doPrivileged(new PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                    Constructor ctor = clazz.getDeclaredConstructor((Class[]) null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                    if (ctor != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                        ctor.setAccessible(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                    return ctor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                } catch (SecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                } catch (NoSuchMethodException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        return (Constructor)ctor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    private static synchronized AWTKeyStroke getCachedStroke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        (char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        if (cache == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            cache = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        if (cacheKey == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                cacheKey = (AWTKeyStroke)ctor.newInstance((Object[]) null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            } catch (InstantiationException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            } catch (IllegalAccessException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            } catch (InvocationTargetException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        cacheKey.keyChar = keyChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        cacheKey.keyCode = keyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        cacheKey.modifiers = mapNewModifiers(mapOldModifiers(modifiers));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        cacheKey.onKeyRelease = onKeyRelease;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        AWTKeyStroke stroke = (AWTKeyStroke)cache.get(cacheKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        if (stroke == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            stroke = cacheKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            cache.put(stroke, stroke);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            cacheKey = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        return stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * Returns a shared instance of an <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * that represents a <code>KEY_TYPED</code> event for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     * specified character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * @param keyChar the character value for a keyboard key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * @return an <code>AWTKeyStroke</code> object for that key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        return getCachedStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * Returns a shared instance of an {@code AWTKeyStroke}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * that represents a {@code KEY_TYPED} event for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * specified Character object and a set of modifiers. Note
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * that the first parameter is of type Character rather than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * char. This is to avoid inadvertent clashes with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * calls to <code>getAWTKeyStroke(int keyCode, int modifiers)</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * The modifiers consist of any combination of following:<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * <li>java.awt.event.InputEvent.META_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * The old modifiers listed below also can be used, but they are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     * mapped to _DOWN_ modifiers. <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * <li>java.awt.event.InputEvent.SHIFT_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * <li>java.awt.event.InputEvent.CTRL_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     * <li>java.awt.event.InputEvent.META_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     * <li>java.awt.event.InputEvent.ALT_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * also can be used, but they are mapped to _DOWN_ modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * Since these numbers are all different powers of two, any combination of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * them is an integer in which each bit represents a different modifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * key. Use 0 to specify no modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * @param keyChar the Character object for a keyboard character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * @param modifiers a bitwise-ored combination of any modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * @return an <code>AWTKeyStroke</code> object for that key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * @throws IllegalArgumentException if <code>keyChar</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     *       <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * @see java.awt.event.InputEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        if (keyChar == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            throw new IllegalArgumentException("keyChar cannot be null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        return getCachedStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                               modifiers, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * Returns a shared instance of an <code>AWTKeyStroke</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * given a numeric key code and a set of modifiers, specifying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * whether the key is activated when it is pressed or released.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * The "virtual key" constants defined in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * <code>java.awt.event.KeyEvent</code> can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * used to specify the key code. For example:<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * <li><code>java.awt.event.KeyEvent.VK_ENTER</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * <li><code>java.awt.event.KeyEvent.VK_TAB</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * <li><code>java.awt.event.KeyEvent.VK_SPACE</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * </ul>
2473
3f4bbd3be2f1 6680988: KeyEvent is still missing VK values for many keyboards
yan
parents: 2
diff changeset
   332
     * Alternatively, the key code may be obtained by calling
3f4bbd3be2f1 6680988: KeyEvent is still missing VK values for many keyboards
yan
parents: 2
diff changeset
   333
     * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
3f4bbd3be2f1 6680988: KeyEvent is still missing VK values for many keyboards
yan
parents: 2
diff changeset
   334
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     * The modifiers consist of any combination of:<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * <li>java.awt.event.InputEvent.META_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     * The old modifiers <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * <li>java.awt.event.InputEvent.SHIFT_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * <li>java.awt.event.InputEvent.CTRL_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * <li>java.awt.event.InputEvent.META_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * <li>java.awt.event.InputEvent.ALT_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * also can be used, but they are mapped to _DOWN_ modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * Since these numbers are all different powers of two, any combination of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     * them is an integer in which each bit represents a different modifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * key. Use 0 to specify no modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * @param keyCode an int specifying the numeric code for a keyboard key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * @param modifiers a bitwise-ored combination of any modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * @param onKeyRelease <code>true</code> if the <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     *        should represent a key release; <code>false</code> otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * @return an AWTKeyStroke object for that key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * @see java.awt.event.KeyEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * @see java.awt.event.InputEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                                               boolean onKeyRelease) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                               onKeyRelease);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * Returns a shared instance of an <code>AWTKeyStroke</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * given a numeric key code and a set of modifiers. The returned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * <code>AWTKeyStroke</code> will correspond to a key press.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * The "virtual key" constants defined in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     * <code>java.awt.event.KeyEvent</code> can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     * used to specify the key code. For example:<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * <li><code>java.awt.event.KeyEvent.VK_ENTER</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * <li><code>java.awt.event.KeyEvent.VK_TAB</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * <li><code>java.awt.event.KeyEvent.VK_SPACE</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * The modifiers consist of any combination of:<ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * <li>java.awt.event.InputEvent.META_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * The old modifiers <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * <li>java.awt.event.InputEvent.SHIFT_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * <li>java.awt.event.InputEvent.CTRL_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * <li>java.awt.event.InputEvent.META_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * <li>java.awt.event.InputEvent.ALT_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * also can be used, but they are mapped to _DOWN_ modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * Since these numbers are all different powers of two, any combination of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * them is an integer in which each bit represents a different modifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * key. Use 0 to specify no modifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * @param keyCode an int specifying the numeric code for a keyboard key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     * @param modifiers a bitwise-ored combination of any modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * @return an <code>AWTKeyStroke</code> object for that key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * @see java.awt.event.KeyEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * @see java.awt.event.InputEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                               false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     * Returns an <code>AWTKeyStroke</code> which represents the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
     * stroke which generated a given <code>KeyEvent</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
     * This method obtains the keyChar from a <code>KeyTyped</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
     * event, and the keyCode from a <code>KeyPressed</code> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * <code>KeyReleased</code> event. The <code>KeyEvent</code> modifiers are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     * obtained for all three types of <code>KeyEvent</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * @param anEvent the <code>KeyEvent</code> from which to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     *      obtain the <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * @throws NullPointerException if <code>anEvent</code> is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     * @return the <code>AWTKeyStroke</code> that precipitated the event
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        int id = anEvent.getID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        switch(id) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
          case KeyEvent.KEY_PRESSED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
          case KeyEvent.KEY_RELEASED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            return getCachedStroke(KeyEvent.CHAR_UNDEFINED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                                   anEvent.getKeyCode(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                                   anEvent.getModifiers(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                                   (id == KeyEvent.KEY_RELEASED));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
          case KeyEvent.KEY_TYPED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            return getCachedStroke(anEvent.getKeyChar(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                                   KeyEvent.VK_UNDEFINED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                                   anEvent.getModifiers(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                                   false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
          default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            // Invalid ID for this KeyEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * Parses a string and returns an <code>AWTKeyStroke</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * The string must have the following syntax:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     *    &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     *    modifiers := shift | control | ctrl | meta | alt | altGraph
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     *    typedID := typed &lt;typedKey&gt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     *    typedKey := string of length 1 giving Unicode character.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     *    pressedReleasedID := (pressed | released) key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     *    key := KeyEvent key code name, i.e. the name following "VK_".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * If typed, pressed or released is not specified, pressed is assumed. Here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * are some examples:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     *     "INSERT" => getAWTKeyStroke(KeyEvent.VK_INSERT, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     *     "control DELETE" => getAWTKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     *     "alt shift X" => getAWTKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     *     "alt shift released X" => getAWTKeyStroke(KeyEvent.VK_X, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     *     "typed a" => getAWTKeyStroke('a');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     * @param s a String formatted as described above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * @return an <code>AWTKeyStroke</code> object for that String
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * @throws IllegalArgumentException if <code>s</code> is <code>null</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     *        or is formatted incorrectly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    public static AWTKeyStroke getAWTKeyStroke(String s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        if (s == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            throw new IllegalArgumentException("String cannot be null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        final String errmsg = "String formatted incorrectly";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        StringTokenizer st = new StringTokenizer(s, " ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        int mask = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        boolean released = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        boolean typed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        boolean pressed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        synchronized (AWTKeyStroke.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            if (modifierKeywords == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                Map uninitializedMap = new HashMap(8, 1.0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                uninitializedMap.put("shift",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                                     Integer.valueOf(InputEvent.SHIFT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                                                     |InputEvent.SHIFT_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                uninitializedMap.put("control",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                                     Integer.valueOf(InputEvent.CTRL_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                                                     |InputEvent.CTRL_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                uninitializedMap.put("ctrl",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                                     Integer.valueOf(InputEvent.CTRL_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                                                     |InputEvent.CTRL_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                uninitializedMap.put("meta",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                                     Integer.valueOf(InputEvent.META_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                                                     |InputEvent.META_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                uninitializedMap.put("alt",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                                     Integer.valueOf(InputEvent.ALT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                                                     |InputEvent.ALT_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                uninitializedMap.put("altGraph",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                                     Integer.valueOf(InputEvent.ALT_GRAPH_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                                                     |InputEvent.ALT_GRAPH_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                uninitializedMap.put("button1",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                                     Integer.valueOf(InputEvent.BUTTON1_DOWN_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                uninitializedMap.put("button2",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                                     Integer.valueOf(InputEvent.BUTTON2_DOWN_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                uninitializedMap.put("button3",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                                     Integer.valueOf(InputEvent.BUTTON3_DOWN_MASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                modifierKeywords =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                    Collections.synchronizedMap(uninitializedMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        int count = st.countTokens();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        for (int i = 1; i <= count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            String token = st.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            if (typed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                if (token.length() != 1 || i != count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                    throw new IllegalArgumentException(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                return getCachedStroke(token.charAt(0), KeyEvent.VK_UNDEFINED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                                       mask, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            if (pressed || released || i == count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                if (i != count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                    throw new IllegalArgumentException(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                String keyCodeName = "VK_" + token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                int keyCode = getVKValue(keyCodeName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                return getCachedStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                                       mask, released);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            if (token.equals("released")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                released = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            if (token.equals("pressed")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                pressed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            if (token.equals("typed")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                typed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            Integer tokenMask = (Integer)modifierKeywords.get(token);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            if (tokenMask != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                mask |= tokenMask.intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                throw new IllegalArgumentException(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        throw new IllegalArgumentException(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    private static VKCollection getVKCollection() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        if (vks == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            vks = new VKCollection();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        return vks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     * Returns the integer constant for the KeyEvent.VK field named
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     * <code>key</code>. This will throw an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * <code>IllegalArgumentException</code> if <code>key</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     * not a valid constant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    private static int getVKValue(String key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        VKCollection vkCollect = getVKCollection();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        Integer value = vkCollect.findCode(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        if (value == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            int keyCode = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            final String errmsg = "String formatted incorrectly";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                keyCode = KeyEvent.class.getField(key).getInt(KeyEvent.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            } catch (NoSuchFieldException nsfe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                throw new IllegalArgumentException(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
            } catch (IllegalAccessException iae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                throw new IllegalArgumentException(errmsg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            value = Integer.valueOf(keyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            vkCollect.put(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        return value.intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * Returns the character for this <code>AWTKeyStroke</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * @return a char value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * @see #getAWTKeyStroke(char)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * @see KeyEvent#getKeyChar
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    public final char getKeyChar() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        return keyChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * Returns the numeric key code for this <code>AWTKeyStroke</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
     * @return an int containing the key code value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     * @see #getAWTKeyStroke(int,int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * @see KeyEvent#getKeyCode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    public final int getKeyCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        return keyCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * Returns the modifier keys for this <code>AWTKeyStroke</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     * @return an int containing the modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * @see #getAWTKeyStroke(int,int)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    public final int getModifiers() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        return modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
     * Returns whether this <code>AWTKeyStroke</code> represents a key release.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * @return <code>true</code> if this <code>AWTKeyStroke</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     *          represents a key release; <code>false</code> otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * @see #getAWTKeyStroke(int,int,boolean)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    public final boolean isOnKeyRelease() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        return onKeyRelease;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * Returns the type of <code>KeyEvent</code> which corresponds to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * this <code>AWTKeyStroke</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * @return <code>KeyEvent.KEY_PRESSED</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     *         <code>KeyEvent.KEY_TYPED</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     *         or <code>KeyEvent.KEY_RELEASED</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * @see java.awt.event.KeyEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    public final int getKeyEventType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        if (keyCode == KeyEvent.VK_UNDEFINED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            return KeyEvent.KEY_TYPED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            return (onKeyRelease)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                ? KeyEvent.KEY_RELEASED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                : KeyEvent.KEY_PRESSED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * Returns a numeric value for this object that is likely to be unique,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * making it a good choice as the index value in a hash table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * @return an int that represents this object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    public int hashCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        return (((int)keyChar) + 1) * (2 * (keyCode + 1)) * (modifiers + 1) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            (onKeyRelease ? 1 : 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     * Returns true if this object is identical to the specified object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
     * @param anObject the Object to compare this object to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     * @return true if the objects are identical
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    public final boolean equals(Object anObject) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
        if (anObject instanceof AWTKeyStroke) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            AWTKeyStroke ks = (AWTKeyStroke)anObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            return (ks.keyChar == keyChar && ks.keyCode == keyCode &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                    ks.onKeyRelease == onKeyRelease &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                    ks.modifiers == modifiers);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     * Returns a string that displays and identifies this object's properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * The <code>String</code> returned by this method can be passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     * as a parameter to <code>getAWTKeyStroke(String)</code> to produce
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * a key stroke equal to this key stroke.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * @return a String representation of this object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     * @see #getAWTKeyStroke(String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        if (keyCode == KeyEvent.VK_UNDEFINED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            return getModifiersText(modifiers) + "typed " + keyChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            return getModifiersText(modifiers) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                (onKeyRelease ? "released" : "pressed") + " " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                getVKText(keyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    static String getModifiersText(int modifiers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        StringBuilder buf = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            buf.append("shift ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            buf.append("ctrl ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        if ((modifiers & InputEvent.META_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            buf.append("meta ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            buf.append("alt ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
            buf.append("altGraph ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        if ((modifiers & InputEvent.BUTTON1_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            buf.append("button1 ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        if ((modifiers & InputEvent.BUTTON2_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            buf.append("button2 ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        if ((modifiers & InputEvent.BUTTON3_DOWN_MASK) != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            buf.append("button3 ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        return buf.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    static String getVKText(int keyCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        VKCollection vkCollect = getVKCollection();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        Integer key = Integer.valueOf(keyCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        String name = vkCollect.findName(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        if (name != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            return name.substring(3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        int expected_modifiers =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
            (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        Field[] fields = KeyEvent.class.getDeclaredFields();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        for (int i = 0; i < fields.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                if (fields[i].getModifiers() == expected_modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                    && fields[i].getType() == Integer.TYPE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    && fields[i].getName().startsWith("VK_")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                    && fields[i].getInt(KeyEvent.class) == keyCode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    name = fields[i].getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                    vkCollect.put(name, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                    return name.substring(3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            } catch (IllegalAccessException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        return "UNKNOWN";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     * Returns a cached instance of <code>AWTKeyStroke</code> (or a subclass of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     * <code>AWTKeyStroke</code>) which is equal to this instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * @return a cached instance which is equal to this instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    protected Object readResolve() throws java.io.ObjectStreamException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        synchronized (AWTKeyStroke.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            Class newClass = getClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            if (!newClass.equals(ctor.getDeclaringClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                registerSubclass(newClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    private static int mapOldModifiers(int modifiers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
            modifiers |= InputEvent.SHIFT_DOWN_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        if ((modifiers & InputEvent.ALT_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            modifiers |= InputEvent.ALT_DOWN_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        if ((modifiers & InputEvent.CTRL_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
            modifiers |= InputEvent.CTRL_DOWN_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        if ((modifiers & InputEvent.META_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            modifiers |= InputEvent.META_DOWN_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        modifiers &= InputEvent.SHIFT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            | InputEvent.ALT_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            | InputEvent.ALT_GRAPH_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
            | InputEvent.CTRL_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            | InputEvent.META_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            | InputEvent.BUTTON1_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
            | InputEvent.BUTTON2_DOWN_MASK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            | InputEvent.BUTTON3_DOWN_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        return modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    private static int mapNewModifiers(int modifiers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            modifiers |= InputEvent.SHIFT_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
        if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            modifiers |= InputEvent.ALT_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        if ((modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            modifiers |= InputEvent.ALT_GRAPH_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            modifiers |= InputEvent.CTRL_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        if ((modifiers & InputEvent.META_DOWN_MASK) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            modifiers |= InputEvent.META_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        return modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
class VKCollection {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
    Map code2name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    Map name2code;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
    public VKCollection() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        code2name = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        name2code = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    public synchronized void put(String name, Integer code) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        assert((name != null) && (code != null));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        assert(findName(code) == null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        assert(findCode(name) == null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        code2name.put(code, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        name2code.put(name, code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
    public synchronized Integer findCode(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        assert(name != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        return (Integer)name2code.get(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
    public synchronized String findName(Integer code) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        assert(code != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        return (String)code2name.get(code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
}