src/share/classes/java/awt/AWTKeyStroke.java

Print this page




  69 
  70     private static Map<String, Integer> modifierKeywords;
  71     /**
  72      * Associates VK_XXX (as a String) with code (as Integer). This is
  73      * done to avoid the overhead of the reflective call to find the
  74      * constant.
  75      */
  76     private static VKCollection vks;
  77 
  78     //A key for the collection of AWTKeyStrokes within AppContext.
  79     private static Object APP_CONTEXT_CACHE_KEY = new Object();
  80     //A key withing the cache
  81     private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke();
  82 
  83     /*
  84      * Reads keystroke class from AppContext and if null, puts there the
  85      * AWTKeyStroke class.
  86      * Must be called under locked AWTKeyStro
  87      */
  88     private static Class<AWTKeyStroke> getAWTKeyStrokeClass() {
  89         Class<AWTKeyStroke> clazz = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);

  90         if (clazz == null) {
  91             clazz = AWTKeyStroke.class;
  92             AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class);
  93         }
  94         return clazz;
  95     }
  96 
  97     private char keyChar = KeyEvent.CHAR_UNDEFINED;
  98     private int keyCode = KeyEvent.VK_UNDEFINED;
  99     private int modifiers;
 100     private boolean onKeyRelease;
 101 
 102     static {
 103         /* ensure that the necessary native libraries are loaded */
 104         Toolkit.loadLibraries();
 105     }
 106 
 107     /**
 108      * Constructs an <code>AWTKeyStroke</code> with default values.
 109      * The default values used are:


 165      * method, the factory methods will return instances of the specified
 166      * Class. The specified Class must be either <code>AWTKeyStroke</code>
 167      * or derived from <code>AWTKeyStroke</code>, and it must have a
 168      * no-arg constructor. The constructor can be of any accessibility,
 169      * including <code>private</code>. This operation
 170      * flushes the current <code>AWTKeyStroke</code> cache.
 171      *
 172      * @param subclass the new Class of which the factory methods should create
 173      *        instances
 174      * @throws IllegalArgumentException if subclass is <code>null</code>,
 175      *         or if subclass does not have a no-arg constructor
 176      * @throws ClassCastException if subclass is not
 177      *         <code>AWTKeyStroke</code>, or a class derived from
 178      *         <code>AWTKeyStroke</code>
 179      */
 180     protected static void registerSubclass(Class<?> subclass) {
 181         if (subclass == null) {
 182             throw new IllegalArgumentException("subclass cannot be null");
 183         }
 184         synchronized (AWTKeyStroke.class) {

 185             Class<AWTKeyStroke> keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
 186             if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
 187                 // Already registered
 188                 return;
 189             }
 190         }
 191         if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
 192             throw new ClassCastException("subclass is not derived from AWTKeyStroke");
 193         }
 194 
 195         Constructor ctor = getCtor(subclass);
 196 
 197         String couldNotInstantiate = "subclass could not be instantiated";
 198 
 199         if (ctor == null) {
 200             throw new IllegalArgumentException(couldNotInstantiate);
 201         }
 202         try {
 203             AWTKeyStroke stroke = (AWTKeyStroke)ctor.newInstance((Object[]) null);
 204             if (stroke == null) {
 205                 throw new IllegalArgumentException(couldNotInstantiate);
 206             }
 207         } catch (NoSuchMethodError e) {
 208             throw new IllegalArgumentException(couldNotInstantiate);
 209         } catch (ExceptionInInitializerError e) {
 210             throw new IllegalArgumentException(couldNotInstantiate);
 211         } catch (InstantiationException e) {
 212             throw new IllegalArgumentException(couldNotInstantiate);
 213         } catch (IllegalAccessException e) {
 214             throw new IllegalArgumentException(couldNotInstantiate);
 215         } catch (InvocationTargetException e) {
 216             throw new IllegalArgumentException(couldNotInstantiate);
 217         }
 218 
 219         synchronized (AWTKeyStroke.class) {
 220             AppContext.getAppContext().put(AWTKeyStroke.class, subclass);
 221             AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY);
 222             AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
 223         }
 224     }
 225 
 226     /* returns noarg Constructor for class with accessible flag. No security
 227        threat as accessible flag is set only for this Constructor object,
 228        not for Class constructor.
 229      */
 230     private static Constructor getCtor(final Class clazz)
 231     {
 232         Constructor ctor = AccessController.doPrivileged(new PrivilegedAction<Constructor>() {
 233             public Constructor run() {
 234                 try {
 235                     Constructor ctor = clazz.getDeclaredConstructor((Class[]) null);
 236                     if (ctor != null) {
 237                         ctor.setAccessible(true);
 238                     }
 239                     return ctor;
 240                 } catch (SecurityException e) {
 241                 } catch (NoSuchMethodException e) {
 242                 }
 243                 return null;
 244             }
 245         });
 246         return ctor;
 247     }
 248 
 249     private static synchronized AWTKeyStroke getCachedStroke
 250         (char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
 251     {

 252         Map<AWTKeyStroke, AWTKeyStroke> cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY);

 253         AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY);
 254 
 255         if (cache == null) {
 256             cache = new HashMap<>();
 257             AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache);
 258         }
 259 
 260         if (cacheKey == null) {
 261             try {
 262                 Class<AWTKeyStroke> clazz = getAWTKeyStrokeClass();
 263                 cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null);
 264                 AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey);
 265             } catch (InstantiationException e) {
 266                 assert(false);
 267             } catch (IllegalAccessException e) {
 268                 assert(false);
 269             } catch (InvocationTargetException e) {
 270                 assert(false);
 271             }
 272         }




  69 
  70     private static Map<String, Integer> modifierKeywords;
  71     /**
  72      * Associates VK_XXX (as a String) with code (as Integer). This is
  73      * done to avoid the overhead of the reflective call to find the
  74      * constant.
  75      */
  76     private static VKCollection vks;
  77 
  78     //A key for the collection of AWTKeyStrokes within AppContext.
  79     private static Object APP_CONTEXT_CACHE_KEY = new Object();
  80     //A key withing the cache
  81     private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke();
  82 
  83     /*
  84      * Reads keystroke class from AppContext and if null, puts there the
  85      * AWTKeyStroke class.
  86      * Must be called under locked AWTKeyStro
  87      */
  88     private static Class<AWTKeyStroke> getAWTKeyStrokeClass() {
  89         @SuppressWarnings("unchecked")
  90         Class<AWTKeyStroke> clazz = (Class<AWTKeyStroke>)AppContext.getAppContext().get(AWTKeyStroke.class);
  91         if (clazz == null) {
  92             clazz = AWTKeyStroke.class;
  93             AppContext.getAppContext().put(AWTKeyStroke.class, AWTKeyStroke.class);
  94         }
  95         return clazz;
  96     }
  97 
  98     private char keyChar = KeyEvent.CHAR_UNDEFINED;
  99     private int keyCode = KeyEvent.VK_UNDEFINED;
 100     private int modifiers;
 101     private boolean onKeyRelease;
 102 
 103     static {
 104         /* ensure that the necessary native libraries are loaded */
 105         Toolkit.loadLibraries();
 106     }
 107 
 108     /**
 109      * Constructs an <code>AWTKeyStroke</code> with default values.
 110      * The default values used are:


 166      * method, the factory methods will return instances of the specified
 167      * Class. The specified Class must be either <code>AWTKeyStroke</code>
 168      * or derived from <code>AWTKeyStroke</code>, and it must have a
 169      * no-arg constructor. The constructor can be of any accessibility,
 170      * including <code>private</code>. This operation
 171      * flushes the current <code>AWTKeyStroke</code> cache.
 172      *
 173      * @param subclass the new Class of which the factory methods should create
 174      *        instances
 175      * @throws IllegalArgumentException if subclass is <code>null</code>,
 176      *         or if subclass does not have a no-arg constructor
 177      * @throws ClassCastException if subclass is not
 178      *         <code>AWTKeyStroke</code>, or a class derived from
 179      *         <code>AWTKeyStroke</code>
 180      */
 181     protected static void registerSubclass(Class<?> subclass) {
 182         if (subclass == null) {
 183             throw new IllegalArgumentException("subclass cannot be null");
 184         }
 185         synchronized (AWTKeyStroke.class) {
 186             @SuppressWarnings("unchecked")
 187             Class<AWTKeyStroke> keyStrokeClass = (Class)AppContext.getAppContext().get(AWTKeyStroke.class);
 188             if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
 189                 // Already registered
 190                 return;
 191             }
 192         }
 193         if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
 194             throw new ClassCastException("subclass is not derived from AWTKeyStroke");
 195         }
 196 
 197         Constructor<?> ctor = getCtor(subclass);
 198 
 199         String couldNotInstantiate = "subclass could not be instantiated";
 200 
 201         if (ctor == null) {
 202             throw new IllegalArgumentException(couldNotInstantiate);
 203         }
 204         try {
 205             AWTKeyStroke stroke = (AWTKeyStroke)ctor.newInstance((Object[]) null);
 206             if (stroke == null) {
 207                 throw new IllegalArgumentException(couldNotInstantiate);
 208             }
 209         } catch (NoSuchMethodError e) {
 210             throw new IllegalArgumentException(couldNotInstantiate);
 211         } catch (ExceptionInInitializerError e) {
 212             throw new IllegalArgumentException(couldNotInstantiate);
 213         } catch (InstantiationException e) {
 214             throw new IllegalArgumentException(couldNotInstantiate);
 215         } catch (IllegalAccessException e) {
 216             throw new IllegalArgumentException(couldNotInstantiate);
 217         } catch (InvocationTargetException e) {
 218             throw new IllegalArgumentException(couldNotInstantiate);
 219         }
 220 
 221         synchronized (AWTKeyStroke.class) {
 222             AppContext.getAppContext().put(AWTKeyStroke.class, subclass);
 223             AppContext.getAppContext().remove(APP_CONTEXT_CACHE_KEY);
 224             AppContext.getAppContext().remove(APP_CONTEXT_KEYSTROKE_KEY);
 225         }
 226     }
 227 
 228     /* returns noarg Constructor for class with accessible flag. No security
 229        threat as accessible flag is set only for this Constructor object,
 230        not for Class constructor.
 231      */
 232     private static Constructor<?> getCtor(final Class<?> clazz)
 233     {
 234         Constructor<?> ctor = AccessController.doPrivileged(new PrivilegedAction<Constructor<?>>() {
 235             public Constructor<?> run() {
 236                 try {
 237                     Constructor<?> ctor = clazz.getDeclaredConstructor((Class<?>[]) null);
 238                     if (ctor != null) {
 239                         ctor.setAccessible(true);
 240                     }
 241                     return ctor;
 242                 } catch (SecurityException e) {
 243                 } catch (NoSuchMethodException e) {
 244                 }
 245                 return null;
 246             }
 247         });
 248         return ctor;
 249     }
 250 
 251     private static synchronized AWTKeyStroke getCachedStroke
 252         (char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
 253     {
 254         @SuppressWarnings("unchecked")
 255         Map<AWTKeyStroke, AWTKeyStroke> cache = (Map)AppContext.getAppContext().get(APP_CONTEXT_CACHE_KEY);
 256         @SuppressWarnings("unchecked")
 257         AWTKeyStroke cacheKey = (AWTKeyStroke)AppContext.getAppContext().get(APP_CONTEXT_KEYSTROKE_KEY);
 258 
 259         if (cache == null) {
 260             cache = new HashMap<>();
 261             AppContext.getAppContext().put(APP_CONTEXT_CACHE_KEY, cache);
 262         }
 263 
 264         if (cacheKey == null) {
 265             try {
 266                 Class<AWTKeyStroke> clazz = getAWTKeyStrokeClass();
 267                 cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null);
 268                 AppContext.getAppContext().put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey);
 269             } catch (InstantiationException e) {
 270                 assert(false);
 271             } catch (IllegalAccessException e) {
 272                 assert(false);
 273             } catch (InvocationTargetException e) {
 274                 assert(false);
 275             }
 276         }