Source Code Cross Referenced for AWTKeyStroke.java in  » 6.0-JDK-Core » AWT » java » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » AWT » java.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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