OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [awt/] [AWTKeyStroke.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* AWTKeyStroke.java -- an immutable key stroke
2
   Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.awt;
40
 
41
import java.awt.event.InputEvent;
42
import java.awt.event.KeyEvent;
43
import java.io.ObjectStreamException;
44
import java.io.Serializable;
45
import java.lang.reflect.Constructor;
46
import java.lang.reflect.Field;
47
import java.lang.reflect.InvocationTargetException;
48
import java.security.AccessController;
49
import java.security.PrivilegedAction;
50
import java.security.PrivilegedActionException;
51
import java.security.PrivilegedExceptionAction;
52
import java.util.HashMap;
53
import java.util.LinkedHashMap;
54
import java.util.Map;
55
import java.util.StringTokenizer;
56
 
57
/**
58
 * This class mirrors KeyEvents, representing both low-level key presses and
59
 * key releases, and high level key typed inputs. However, this class forms
60
 * immutable strokes, and can be efficiently reused via the factory methods
61
 * for creating them.
62
 *
63
 * <p>For backwards compatibility with Swing, this supports a way to build
64
 * instances of a subclass, using reflection, provided the subclass has a
65
 * no-arg constructor (of any accessibility).
66
 *
67
 * @author Eric Blake (ebb9@email.byu.edu)
68
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
69
 * @see #getAWTKeyStroke(char)
70
 * @since 1.4
71
 * @status updated to 1.4
72
 */
73
public class AWTKeyStroke implements Serializable
74
{
75
  /**
76
   * Compatible with JDK 1.4+.
77
   */
78
  private static final long serialVersionUID = -6430539691155161871L;
79
 
80
  /** The mask for modifiers. */
81
  private static final int MODIFIERS_MASK = 0x3fef;
82
 
83
  /**
84
   * The cache of recently created keystrokes. This maps KeyStrokes to
85
   * KeyStrokes in a cache which removes the least recently accessed entry,
86
   * under the assumption that garbage collection of a new keystroke is
87
   * easy when we find the old one that it matches in the cache.
88
   */
89
  private static final LinkedHashMap<AWTKeyStroke,AWTKeyStroke> cache =
90
    new LinkedHashMap<AWTKeyStroke,AWTKeyStroke>(11, 0.75f, true)
91
  {
92
    /** The largest the keystroke cache can grow. */
93
    private static final int MAX_CACHE_SIZE = 2048;
94
 
95
    /** Prune stale entries. */
96
    protected boolean removeEldestEntry(Map.Entry<AWTKeyStroke,AWTKeyStroke>
97
                                        eldest)
98
    {
99
      return size() > MAX_CACHE_SIZE;
100
    }
101
  };
102
 
103
  /** The most recently generated keystroke, or null. */
104
  private static AWTKeyStroke recent;
105
 
106
  /**
107
   * The no-arg constructor of a subclass, or null to use AWTKeyStroke. Note
108
   * that this will be left accessible, to get around private access; but
109
   * it should not be a security risk as it is highly unlikely that creating
110
   * protected instances of the subclass via reflection will do much damage.
111
   */
112
  private static Constructor ctor;
113
 
114
  /**
115
   * A table of keyCode names to values.  This is package-private to
116
   * avoid an accessor method.
117
   *
118
   * @see #getAWTKeyStroke(String)
119
   */
120
  static final HashMap<String,Object> vktable = new HashMap<String,Object>();
121
  static
122
  {
123
    // Using reflection saves the hassle of keeping this in sync with KeyEvent,
124
    // at the price of an expensive initialization.
125
    AccessController.doPrivileged(new PrivilegedAction()
126
      {
127
        public Object run()
128
        {
129
          Field[] fields = KeyEvent.class.getFields();
130
          int i = fields.length;
131
          try
132
            {
133
              while (--i >= 0)
134
                {
135
                  Field f = fields[i];
136
                  String name = f.getName();
137
                  if (name.startsWith("VK_"))
138
                    vktable.put(name.substring(3), f.get(null));
139
                }
140
            }
141
          catch (Exception e)
142
            {
143
              throw (Error) new InternalError().initCause(e);
144
            }
145
          return null;
146
        }
147
      });
148
  }
149
 
150
  /**
151
   * The typed character, or CHAR_UNDEFINED for key presses and releases.
152
   *
153
   * @serial the keyChar
154
   */
155
  private char keyChar;
156
 
157
  /**
158
   * The virtual key code, or VK_UNDEFINED for key typed. Package visible for
159
   * use by Component.
160
   *
161
   * @serial the keyCode
162
   */
163
  int keyCode;
164
 
165
  /**
166
   * The modifiers in effect. To match Sun, this stores the old style masks
167
   * for shift, control, alt, meta, and alt-graph (but not button1); as well
168
   * as the new style of extended modifiers for all modifiers.
169
   *
170
   * @serial bitwise or of the *_DOWN_MASK modifiers
171
   */
172
  private int modifiers;
173
 
174
  /**
175
   * True if this is a key release; should only be true if keyChar is
176
   * CHAR_UNDEFINED.
177
   *
178
   * @serial true to distinguish key pressed from key released
179
   */
180
  private boolean onKeyRelease;
181
 
182
  /**
183
   * Construct a keystroke with default values: it will be interpreted as a
184
   * key typed event with an invalid character and no modifiers. Client code
185
   * should use the factory methods instead.
186
   *
187
   * @see #getAWTKeyStroke(char)
188
   * @see #getAWTKeyStroke(Character, int)
189
   * @see #getAWTKeyStroke(int, int, boolean)
190
   * @see #getAWTKeyStroke(int, int)
191
   * @see #getAWTKeyStrokeForEvent(KeyEvent)
192
   * @see #getAWTKeyStroke(String)
193
   */
194
  protected AWTKeyStroke()
195
  {
196
    keyChar = KeyEvent.CHAR_UNDEFINED;
197
  }
198
 
199
  /**
200
   * Construct a keystroke with the given values. Client code should use the
201
   * factory methods instead.
202
   *
203
   * @param keyChar the character entered, if this is a key typed
204
   * @param keyCode the key pressed or released, or VK_UNDEFINED for key typed
205
   * @param modifiers the modifier keys for the keystroke, in old or new style
206
   * @param onKeyRelease true if this is a key release instead of a press
207
   * @see #getAWTKeyStroke(char)
208
   * @see #getAWTKeyStroke(Character, int)
209
   * @see #getAWTKeyStroke(int, int, boolean)
210
   * @see #getAWTKeyStroke(int, int)
211
   * @see #getAWTKeyStrokeForEvent(KeyEvent)
212
   * @see #getAWTKeyStroke(String)
213
   */
214
  protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
215
                         boolean onKeyRelease)
216
  {
217
    this.keyChar = keyChar;
218
    this.keyCode = keyCode;
219
    // No need to call extend(), as only trusted code calls this constructor.
220
    this.modifiers = modifiers;
221
    this.onKeyRelease = onKeyRelease;
222
  }
223
 
224
  /**
225
   * Registers a new subclass as being the type of keystrokes to generate in
226
   * the factory methods. This operation flushes the cache of stored keystrokes
227
   * if the class differs from the current one. The new class must be
228
   * AWTKeyStroke or a subclass, and must have a no-arg constructor (which may
229
   * be private).
230
   *
231
   * @param subclass the new runtime type of generated keystrokes
232
   * @throws IllegalArgumentException subclass doesn't have no-arg constructor
233
   * @throws ClassCastException subclass doesn't extend AWTKeyStroke
234
   */
235
  protected static void registerSubclass(final Class<?> subclass)
236
  {
237
    if (subclass == null)
238
      throw new IllegalArgumentException();
239
    if (subclass.equals(ctor == null ? AWTKeyStroke.class
240
                        : ctor.getDeclaringClass()))
241
      return;
242
    if (subclass.equals(AWTKeyStroke.class))
243
       {
244
         cache.clear();
245
         recent = null;
246
         ctor = null;
247
         return;
248
       }
249
    try
250
      {
251
        ctor = (Constructor) AccessController.doPrivileged
252
          (new PrivilegedExceptionAction()
253
            {
254
              public Object run()
255
                throws NoSuchMethodException, InstantiationException,
256
                       IllegalAccessException, InvocationTargetException
257
              {
258
                Constructor<?> c =
259
                  subclass.getDeclaredConstructor((Class<?>[])null);
260
                c.setAccessible(true);
261
                // Create a new instance, to make sure that we can, and
262
                // to cause any ClassCastException.
263
                AWTKeyStroke dummy = (AWTKeyStroke) c.newInstance();
264
                return c;
265
              }
266
            });
267
      }
268
    catch (PrivilegedActionException e)
269
      {
270
        // e.getCause() will not ever be ClassCastException; that should
271
        // escape on its own.
272
        throw (RuntimeException)
273
          new IllegalArgumentException().initCause(e.getCause());
274
      }
275
    cache.clear();
276
    recent = null;
277
  }
278
 
279
  /**
280
   * Returns a keystroke representing a typed character.
281
   *
282
   * @param keyChar the typed character
283
   * @return the specified keystroke
284
   */
285
  public static AWTKeyStroke getAWTKeyStroke(char keyChar)
286
  {
287
    return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
288
  }
289
 
290
  /**
291
   * Returns a keystroke representing a typed character with the given
292
   * modifiers. Note that keyChar is a <code>Character</code> instead of a
293
   * <code>char</code> to avoid accidental ambiguity with
294
   * <code>getAWTKeyStroke(int, int)</code>. The modifiers are the bitwise
295
   * or of the masks found in {@link InputEvent}; the new style (*_DOWN_MASK)
296
   * is preferred, but the old style will work.
297
   *
298
   * @param keyChar the typed character
299
   * @param modifiers the modifiers, or 0
300
   * @return the specified keystroke
301
   * @throws IllegalArgumentException if keyChar is null
302
   */
303
  public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers)
304
  {
305
    if (keyChar == null)
306
      throw new IllegalArgumentException();
307
    return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
308
                           extend(modifiers), false);
309
  }
310
 
311
  /**
312
   * Returns a keystroke representing a pressed or released key event, with
313
   * the given modifiers. The "virtual key" should be one of the VK_*
314
   * constants in {@link KeyEvent}. The modifiers are the bitwise or of the
315
   * masks found in {@link InputEvent}; the new style (*_DOWN_MASK) is
316
   * preferred, but the old style will work.
317
   *
318
   * @param keyCode the virtual key
319
   * @param modifiers the modifiers, or 0
320
   * @param release true if this is a key release instead of a key press
321
   * @return the specified keystroke
322
   */
323
  public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
324
                                             boolean release)
325
  {
326
    return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
327
                           extend(modifiers), release);
328
  }
329
 
330
  /**
331
   * Returns a keystroke representing a pressed key event, with the given
332
   * modifiers. The "virtual key" should be one of the VK_* constants in
333
   * {@link KeyEvent}. The modifiers are the bitwise or of the masks found
334
   * in {@link InputEvent}; the new style (*_DOWN_MASK) is preferred, but the
335
   * old style will work.
336
   *
337
   * @param keyCode the virtual key
338
   * @param modifiers the modifiers, or 0
339
   * @return the specified keystroke
340
   */
341
  public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers)
342
  {
343
    return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode,
344
                           extend(modifiers), false);
345
  }
346
 
347
  /**
348
   * Returns a keystroke representing what caused the key event.
349
   *
350
   * @param event the key event to convert
351
   * @return the specified keystroke, or null if the event is invalid
352
   * @throws NullPointerException if event is null
353
   */
354
  public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent event)
355
  {
356
    switch (event.id)
357
      {
358
      case KeyEvent.KEY_TYPED:
359
        return getAWTKeyStroke(event.getKeyChar(), KeyEvent.VK_UNDEFINED,
360
                               extend(event.getModifiersEx()), false);
361
      case KeyEvent.KEY_PRESSED:
362
        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, event.getKeyCode(),
363
                               extend(event.getModifiersEx()), false);
364
      case KeyEvent.KEY_RELEASED:
365
        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, event.getKeyCode(),
366
                               extend(event.getModifiersEx()), true);
367
      default:
368
        return null;
369
      }
370
  }
371
 
372
  /**
373
   * Parses a string and returns the keystroke that it represents. The syntax
374
   * for keystrokes is listed below, with tokens separated by an arbitrary
375
   * number of spaces:
376
   * <pre>
377
   * keyStroke := &lt;modifiers&gt;* ( &lt;typedID&gt; | &lt;codeID&gt; )
378
   * modifiers := ( shift | control | ctrl | meta | alt
379
   *                | button1 | button2 | button3 )
380
   * typedID := typed &lt;single Unicode character&gt;
381
   * codeID := ( pressed | released )? &lt;name&gt;
382
   * name := &lt;the KeyEvent field name less the leading "VK_"&gt;
383
   * </pre>
384
   *
385
   * <p>Note that the grammar is rather weak, and not all valid keystrokes
386
   * can be generated in this manner (for example, a typed space, or anything
387
   * with the alt-graph modifier!). The output of AWTKeyStroke.toString()
388
   * will not meet the grammar. If pressed or released is not specified,
389
   * pressed is assumed. Examples:<br>
390
   * <code>
391
   * "INSERT" =&gt; getAWTKeyStroke(KeyEvent.VK_INSERT, 0);<br>
392
   * "control DELETE" =&gt;
393
   *    getAWTKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);<br>
394
   * "alt shift X" =&gt; getAWTKeyStroke(KeyEvent.VK_X,
395
   *    InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);<br>
396
   * "alt shift released X" =&gt; getAWTKeyStroke(KeyEvent.VK_X,
397
   *    InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);<br>
398
   * "typed a" =&gt; getAWTKeyStroke('a');
399
   * </code>
400
   *
401
   * @param s the string to parse
402
   * @throws IllegalArgumentException if s is null or cannot be parsed
403
   * @return the specified keystroke
404
   */
405
  public static AWTKeyStroke getAWTKeyStroke(String s)
406
  {
407
    if (s == null)
408
      throw new IllegalArgumentException("null argument");
409
    StringTokenizer t = new StringTokenizer(s, " ");
410
    if (! t.hasMoreTokens())
411
      throw new IllegalArgumentException("no tokens '" + s + "'");
412
    int modifiers = 0;
413
    boolean released = false;
414
    String token = null;
415
    do
416
      {
417
        token = t.nextToken();
418
        if ("shift".equals(token))
419
          {
420
            modifiers |= KeyEvent.SHIFT_MASK;
421
            modifiers |= KeyEvent.SHIFT_DOWN_MASK;
422
          }
423
        else if ("ctrl".equals(token) || "control".equals(token))
424
          {
425
            modifiers |= KeyEvent.CTRL_MASK;
426
            modifiers |= KeyEvent.CTRL_DOWN_MASK;
427
          }
428
        else if ("meta".equals(token))
429
          {
430
            modifiers |= KeyEvent.META_MASK;
431
            modifiers |= KeyEvent.META_DOWN_MASK;
432
          }
433
        else if ("alt".equals(token))
434
          {
435
            modifiers |= KeyEvent.ALT_MASK;
436
            modifiers |= KeyEvent.ALT_DOWN_MASK;
437
          }
438
        else if ("button1".equals(token))
439
          modifiers |= KeyEvent.BUTTON1_DOWN_MASK;
440
        else if ("button2".equals(token))
441
          modifiers |= KeyEvent.BUTTON2_DOWN_MASK;
442
        else if ("button3".equals(token))
443
          modifiers |= KeyEvent.BUTTON3_DOWN_MASK;
444
        else if ("typed".equals(token))
445
          {
446
            if (t.hasMoreTokens())
447
              {
448
                token = t.nextToken();
449
                if (! t.hasMoreTokens() && token.length() == 1)
450
                  return getAWTKeyStroke(token.charAt(0),
451
                                         KeyEvent.VK_UNDEFINED, modifiers,
452
                                         false);
453
              }
454
            throw new IllegalArgumentException("Invalid 'typed' argument '"
455
                                               + s + "'");
456
          }
457
        else if ("pressed".equals(token))
458
          {
459
            if (t.hasMoreTokens())
460
              token = t.nextToken();
461
            break;
462
          }
463
        else if ("released".equals(token))
464
          {
465
            released = true;
466
            if (t.hasMoreTokens())
467
              token = t.nextToken();
468
            break;
469
          }
470
        else
471
          break;
472
      }
473
    while (t.hasMoreTokens());
474
    // Now token contains the VK name we must parse.
475
    Integer code = (Integer) vktable.get(token);
476
    if (code == null)
477
      throw new IllegalArgumentException("Unknown token '" + token
478
                                         + "' in '" + s + "'");
479
    if (t.hasMoreTokens())
480
      throw new IllegalArgumentException("Too many tokens: " + s);
481
    return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, code.intValue(),
482
                           modifiers, released);
483
  }
484
 
485
  /**
486
   * Returns the character of this keystroke, if it was typed.
487
   *
488
   * @return the character value, or CHAR_UNDEFINED
489
   * @see #getAWTKeyStroke(char)
490
   */
491
  public final char getKeyChar()
492
  {
493
    return keyChar;
494
  }
495
 
496
  /**
497
   * Returns the virtual key code of this keystroke, if it was pressed or
498
   * released. This will be a VK_* constant from KeyEvent.
499
   *
500
   * @return the virtual key code value, or VK_UNDEFINED
501
   * @see #getAWTKeyStroke(int, int)
502
   */
503
  public final int getKeyCode()
504
  {
505
    return keyCode;
506
  }
507
 
508
  /**
509
   * Returns the modifiers for this keystroke. This will be a bitwise or of
510
   * constants from InputEvent; it includes the old style masks for shift,
511
   * control, alt, meta, and alt-graph (but not button1); as well as the new
512
   * style of extended modifiers for all modifiers.
513
   *
514
   * @return the modifiers
515
   * @see #getAWTKeyStroke(Character, int)
516
   * @see #getAWTKeyStroke(int, int)
517
   */
518
  public final int getModifiers()
519
  {
520
    return modifiers;
521
  }
522
 
523
  /**
524
   * Tests if this keystroke is a key release.
525
   *
526
   * @return true if this is a key release
527
   * @see #getAWTKeyStroke(int, int, boolean)
528
   */
529
  public final boolean isOnKeyRelease()
530
  {
531
    return onKeyRelease;
532
  }
533
 
534
  /**
535
   * Returns the AWT event type of this keystroke. This is one of
536
   * {@link KeyEvent#KEY_TYPED}, {@link KeyEvent#KEY_PRESSED}, or
537
   * {@link KeyEvent#KEY_RELEASED}.
538
   *
539
   * @return the key event type
540
   */
541
  public final int getKeyEventType()
542
  {
543
    return keyCode == KeyEvent.VK_UNDEFINED ? KeyEvent.KEY_TYPED
544
      : onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED;
545
  }
546
 
547
  /**
548
   * Returns a hashcode for this key event. It is not documented, but appears
549
   * to be: <code>(getKeyChar() + 1) * (getKeyCode() + 1)
550
   * * (getModifiers() + 1) * 2 + (isOnKeyRelease() ? 1 : 2)</code>.
551
   *
552
   * @return the hashcode
553
   */
554
  public int hashCode()
555
  {
556
    return (keyChar + 1) * (keyCode + 1) * (modifiers + 1) * 2
557
      + (onKeyRelease ? 1 : 2);
558
  }
559
 
560
  /**
561
   * Tests two keystrokes for equality.
562
   *
563
   * @param o the object to test
564
   * @return true if it is equal
565
   */
566
  public final boolean equals(Object o)
567
  {
568
    if (! (o instanceof AWTKeyStroke))
569
      return false;
570
    AWTKeyStroke s = (AWTKeyStroke) o;
571
    return this == o || (keyChar == s.keyChar && keyCode == s.keyCode
572
                         && modifiers == s.modifiers
573
                         && onKeyRelease == s.onKeyRelease);
574
  }
575
 
576
  /**
577
   * Returns a string representation of this keystroke. For typed keystrokes,
578
   * this is <code>"keyChar " + KeyEvent.getKeyModifiersText(getModifiers())
579
   + getKeyChar()</code>; for pressed and released keystrokes, this is
580
   * <code>"keyCode " + KeyEvent.getKeyModifiersText(getModifiers())
581
   * + KeyEvent.getKeyText(getKeyCode())
582
   * + (isOnKeyRelease() ? "-R" : "-P")</code>.
583
   *
584
   * @return a string representation
585
   */
586
  public String toString()
587
  {
588
    if (keyCode == KeyEvent.VK_UNDEFINED)
589
      return "keyChar " + KeyEvent.getKeyModifiersText(modifiers) + keyChar;
590
    return "keyCode " + KeyEvent.getKeyModifiersText(modifiers)
591
      + KeyEvent.getKeyText(keyCode) + (onKeyRelease ? "-R" : "-P");
592
  }
593
 
594
  /**
595
   * Returns a cached version of the deserialized keystroke, if available.
596
   *
597
   * @return a cached replacement
598
   * @throws ObjectStreamException if something goes wrong
599
   */
600
  protected Object readResolve() throws ObjectStreamException
601
  {
602
    AWTKeyStroke s = cache.get(this);
603
    if (s != null)
604
      return s;
605
    cache.put(this, this);
606
    return this;
607
  }
608
 
609
  /**
610
   * Gets the appropriate keystroke, creating one if necessary.
611
   *
612
   * @param keyChar the keyChar
613
   * @param keyCode the keyCode
614
   * @param modifiers the modifiers
615
   * @param release true for key release
616
   * @return the specified keystroke
617
   */
618
  private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode,
619
                                              int modifiers, boolean release)
620
  {
621
    // Check level 0 cache.
622
    AWTKeyStroke stroke = recent; // Avoid thread races.
623
    if (stroke != null && stroke.keyChar == keyChar
624
        && stroke.keyCode == keyCode && stroke.modifiers == modifiers
625
        && stroke.onKeyRelease == release)
626
      return stroke;
627
    // Create a new object, on the assumption that if it has a match in the
628
    // cache, the VM can easily garbage collect it as it is temporary.
629
    Constructor c = ctor; // Avoid thread races.
630
    if (c == null)
631
      stroke = new AWTKeyStroke(keyChar, keyCode, modifiers, release);
632
    else
633
      try
634
        {
635
          stroke = (AWTKeyStroke) c.newInstance();
636
          stroke.keyChar = keyChar;
637
          stroke.keyCode = keyCode;
638
          stroke.modifiers = modifiers;
639
          stroke.onKeyRelease = release;
640
        }
641
      catch (Exception e)
642
        {
643
          throw (Error) new InternalError().initCause(e);
644
        }
645
    // Check level 1 cache.
646
    AWTKeyStroke cached = cache.get(stroke);
647
    if (cached == null)
648
      cache.put(stroke, stroke);
649
    else
650
      stroke = cached;
651
    return recent = stroke;
652
  }
653
 
654
  /**
655
   * Converts the modifiers to the appropriate format.
656
   *
657
   * @param mod the modifiers to convert
658
   * @return the adjusted modifiers
659
   */
660
  private static int extend(int mod)
661
  {
662
    if ((mod & (KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK)) != 0)
663
      mod |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK;
664
    if ((mod & (KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK)) != 0)
665
      mod |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK;
666
    if ((mod & (KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK)) != 0)
667
      mod |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK;
668
    if ((mod & (KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK)) != 0)
669
      mod |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK;
670
    if ((mod & (KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK)) != 0)
671
      mod |= KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK;
672
    if ((mod & KeyEvent.BUTTON1_MASK) != 0)
673
      mod |= KeyEvent.BUTTON1_DOWN_MASK;
674
    return mod & MODIFIERS_MASK;
675
  }
676
} // class AWTKeyStroke

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.