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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [awt/] [AWTKeyStroke.java] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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