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 }
|