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

Java Source Code / Java Documentation
1. JDK Core
2. JDK Modules
3. JDK Modules com.sun
4. JDK Modules com.sun.java
5. JDK Modules Platform
6. JDK Modules sun
7. Open Source Graphic Library
8. Open Source IDE Eclipse
9. Open Source J2EE
10. Open Source JBOSS
11. Open Source JDBC Driver
12. Open Source Library
13. Open Source Library Database
14. Open Source Net
15. Science
16. Sevlet Container
17. SUN GlassFish
18. Swing Library
19. Web Services apache cxf 2.0.1
20. Web Services AXIS2
21. XML
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java Source Code / Java Documentation » 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:        }
w__w___w_.___j__av___a___2___s__._c_om
Home | Contact Us
Copyright 2003 - 07 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.