1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50:
51:
52: public class DefaultKeyboardFocusManager extends KeyboardFocusManager
53: {
54:
59: private class EventDelayRequest implements Comparable
60: {
61:
64: private LinkedList enqueuedKeyEvents = new LinkedList ();
65:
66:
69: public long timestamp;
70:
73: public Component focusedComp;
74:
75:
83: public EventDelayRequest (long timestamp, Component focusedComp)
84: {
85: this.timestamp = timestamp;
86: this.focusedComp = focusedComp;
87: }
88:
89: public int compareTo (Object o)
90: {
91: if (!(o instanceof EventDelayRequest))
92: throw new ClassCastException ();
93:
94: EventDelayRequest request = (EventDelayRequest) o;
95:
96: if (request.timestamp < timestamp)
97: return -1;
98: else if (request.timestamp == timestamp)
99: return 0;
100: else
101: return 1;
102: }
103:
104: public boolean equals (Object o)
105: {
106: if (!(o instanceof EventDelayRequest) || o == null)
107: return false;
108:
109: EventDelayRequest request = (EventDelayRequest) o;
110:
111: return (request.timestamp == timestamp
112: && request.focusedComp == focusedComp);
113: }
114:
115: public void enqueueEvent (KeyEvent e)
116: {
117: KeyEvent last = (KeyEvent) enqueuedKeyEvents.getLast ();
118: if (last != null && e.getWhen () < last.getWhen ())
119: throw new RuntimeException ("KeyEvents enqueued out-of-order");
120:
121: if (e.getWhen () <= timestamp)
122: throw new RuntimeException ("KeyEvents enqueued before starting timestamp");
123:
124: enqueuedKeyEvents.add (e);
125: }
126:
127: public void dispatchEvents ()
128: {
129: int size = enqueuedKeyEvents.size ();
130: for (int i = 0; i < size; i++)
131: {
132: KeyEvent e = (KeyEvent) enqueuedKeyEvents.remove (0);
133: dispatchKeyEvent (e);
134: }
135: }
136:
137: public void discardEvents ()
138: {
139: enqueuedKeyEvents.clear ();
140: }
141: }
142:
143:
147: private AWTKeyStroke waitForKeyStroke = null;
148:
149:
151: private SortedSet delayRequests = new TreeSet ();
152:
153: public DefaultKeyboardFocusManager ()
154: {
155: }
156:
157: public boolean dispatchEvent (AWTEvent e)
158: {
159: if (e instanceof WindowEvent)
160: {
161: Window target = (Window) e.getSource ();
162:
163: if (e.id == WindowEvent.WINDOW_ACTIVATED)
164: setGlobalActiveWindow (target);
165: else if (e.id == WindowEvent.WINDOW_GAINED_FOCUS)
166: setGlobalFocusedWindow (target);
167: else if (e.id != WindowEvent.WINDOW_LOST_FOCUS
168: && e.id != WindowEvent.WINDOW_DEACTIVATED)
169: return false;
170:
171: redispatchEvent(target, e);
172: return true;
173: }
174: else if (e instanceof FocusEvent)
175: {
176: Component target = (Component) e.getSource ();
177:
178: if (e.id == FocusEvent.FOCUS_GAINED)
179: {
180: if (! (target instanceof Window))
181: {
182: if (((FocusEvent) e).isTemporary ())
183: setGlobalFocusOwner (target);
184: else
185: setGlobalPermanentFocusOwner (target);
186: }
187:
188:
189:
190:
191:
192: Container parent = target.getParent ();
193:
194: while (parent != null
195: && !(parent instanceof Window))
196: parent = parent.getParent ();
197:
198:
199:
200: if (! (parent == null && ! (target instanceof Window)))
201: {
202: Window toplevel = parent == null ?
203: (Window) target : (Window) parent;
204:
205: Component focusOwner = getFocusOwner ();
206: if (focusOwner != null
207: && ! (focusOwner instanceof Window))
208: toplevel.setFocusOwner (focusOwner);
209: }
210: }
211: else if (e.id == FocusEvent.FOCUS_LOST)
212: {
213: if (((FocusEvent) e).isTemporary ())
214: setGlobalFocusOwner (null);
215: else
216: setGlobalPermanentFocusOwner (null);
217: }
218:
219: redispatchEvent(target, e);
220:
221: return true;
222: }
223: else if (e instanceof KeyEvent)
224: {
225:
226:
227: Iterator i = getKeyEventDispatchers().iterator();
228:
229: while (i.hasNext ())
230: {
231: KeyEventDispatcher dispatcher = (KeyEventDispatcher) i.next ();
232: if (dispatcher.dispatchKeyEvent ((KeyEvent) e))
233: return true;
234: }
235:
236:
237:
238: Component focusOwner = getGlobalPermanentFocusOwner ();
239:
240: if (focusOwner != null)
241: processKeyEvent (focusOwner, (KeyEvent) e);
242:
243: if (e.isConsumed ())
244: return true;
245:
246: if (enqueueKeyEvent ((KeyEvent) e))
247:
248: return true;
249: else
250:
251:
252:
253: return dispatchKeyEvent ((KeyEvent) e);
254: }
255:
256: return false;
257: }
258:
259: private boolean enqueueKeyEvent (KeyEvent e)
260: {
261: Iterator i = delayRequests.iterator ();
262: boolean oneEnqueued = false;
263: while (i.hasNext ())
264: {
265: EventDelayRequest request = (EventDelayRequest) i.next ();
266: if (e.getWhen () > request.timestamp)
267: {
268: request.enqueueEvent (e);
269: oneEnqueued = true;
270: }
271: }
272: return oneEnqueued;
273: }
274:
275: public boolean dispatchKeyEvent (KeyEvent e)
276: {
277: Component focusOwner = getFocusOwner();
278: if (focusOwner == null)
279: focusOwner = getFocusedWindow();
280:
281: if (focusOwner != null)
282: redispatchEvent(focusOwner, e);
283:
284:
285:
286: Iterator i = getKeyEventPostProcessors().iterator();
287:
288: while (i.hasNext ())
289: {
290: KeyEventPostProcessor processor = (KeyEventPostProcessor) i.next ();
291: if (processor.postProcessKeyEvent ((KeyEvent) e))
292: return true;
293: }
294:
295:
296:
297: if (postProcessKeyEvent (e))
298: return true;
299:
300:
301: return true;
302: }
303:
304: public boolean postProcessKeyEvent (KeyEvent e)
305: {
306:
307:
308:
309: int modifiers = e.getModifiersEx ();
310: if (e.getID() == KeyEvent.KEY_PRESSED
311: && (modifiers & KeyEvent.CTRL_DOWN_MASK) != 0)
312: {
313: Window focusedWindow = getGlobalFocusedWindow ();
314: if (focusedWindow instanceof Frame)
315: {
316: MenuBar menubar = ((Frame) focusedWindow).getMenuBar ();
317:
318: if (menubar != null)
319: {
320:
321:
322:
323: int numMenus = menubar.getMenuCount ();
324:
325: for (int i = 0; i < numMenus; i++)
326: {
327: Menu menu = menubar.getMenu (i);
328: int numItems = menu.getItemCount ();
329:
330: for (int j = 0; j < numItems; j++)
331: {
332: MenuItem item = menu.getItem (j);
333: MenuShortcut shortcut = item.getShortcut ();
334:
335: if (item.isEnabled() && shortcut != null)
336: {
337:
338:
339:
340:
341:
342:
343:
344:
345: if (shortcut.getKey () == e.getKeyCode ()
346: && ((shortcut.usesShiftModifier ()
347: && (modifiers & KeyEvent.SHIFT_DOWN_MASK) != 0)
348: || (! shortcut.usesShiftModifier ()
349: && (modifiers & KeyEvent.SHIFT_DOWN_MASK) == 0)))
350: {
351: item.dispatchEvent (new ActionEvent (item,
352: ActionEvent.ACTION_PERFORMED,
353: item.getActionCommand (),
354: modifiers));
355:
356: return true;
357: }
358: }
359: }
360: }
361: }
362: }
363: }
364: return false;
365: }
366:
367: public void processKeyEvent (Component comp, KeyEvent e)
368: {
369: AWTKeyStroke eventKeystroke = AWTKeyStroke.getAWTKeyStrokeForEvent (e);
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381: AWTKeyStroke oppositeKeystroke = AWTKeyStroke.getAWTKeyStroke (e.getKeyCode (),
382: e.getModifiersEx (),
383: !(e.id == KeyEvent.KEY_RELEASED));
384:
385:
386:
387:
388:
389: if (waitForKeyStroke != null)
390: {
391: if (eventKeystroke.equals(waitForKeyStroke))
392:
393: waitForKeyStroke = null;
394:
395:
396:
397: e.consume();
398: return;
399: }
400:
401: Set forwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
402: Set backwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
403: Set upKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
404: Set downKeystrokes = null;
405: if (comp instanceof Container)
406: downKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
407:
408: if (forwardKeystrokes.contains (eventKeystroke))
409: {
410: waitForKeyStroke = oppositeKeystroke;
411: focusNextComponent (comp);
412: e.consume ();
413: }
414: else if (backwardKeystrokes.contains (eventKeystroke))
415: {
416: waitForKeyStroke = oppositeKeystroke;
417: focusPreviousComponent (comp);
418: e.consume ();
419: }
420: else if (upKeystrokes.contains (eventKeystroke))
421: {
422: waitForKeyStroke = oppositeKeystroke;
423: upFocusCycle (comp);
424: e.consume ();
425: }
426: else if (comp instanceof Container
427: && downKeystrokes.contains (eventKeystroke))
428: {
429: waitForKeyStroke = oppositeKeystroke;
430: downFocusCycle ((Container) comp);
431: e.consume ();
432: }
433: }
434:
435: protected void enqueueKeyEvents (long after, Component untilFocused)
436: {
437: delayRequests.add (new EventDelayRequest (after, untilFocused));
438: }
439:
440: protected void dequeueKeyEvents (long after, Component untilFocused)
441: {
442:
443:
444:
445:
446: if (after < 0)
447: {
448: int size = delayRequests.size ();
449: if (size > 0)
450: delayRequests.remove (delayRequests.first ());
451: }
452: else
453: {
454: EventDelayRequest template = new EventDelayRequest (after, untilFocused);
455: if (delayRequests.contains (template))
456: {
457: EventDelayRequest actual = (EventDelayRequest) delayRequests.tailSet (template).first ();
458: delayRequests.remove (actual);
459: actual.dispatchEvents ();
460: }
461: }
462: }
463:
464: protected void discardKeyEvents (Component comp)
465: {
466:
467:
468: Iterator i = delayRequests.iterator ();
469:
470: while (i.hasNext ())
471: {
472: EventDelayRequest request = (EventDelayRequest) i.next ();
473:
474: if (request.focusedComp == comp
475: || (comp instanceof Container
476: && ((Container) comp).isAncestorOf (request.focusedComp)))
477: request.discardEvents ();
478: }
479: }
480:
481: public void focusPreviousComponent (Component comp)
482: {
483: if (comp != null)
484: comp.transferFocusBackward();
485: }
486:
487: public void focusNextComponent (Component comp)
488: {
489: if (comp != null)
490: comp.transferFocus();
491: }
492:
493: public void upFocusCycle (Component comp)
494: {
495: if (comp != null)
496: comp.transferFocusUpCycle();
497: }
498:
499: public void downFocusCycle (Container cont)
500: {
501: if (cont != null)
502: cont.transferFocusDownCycle();
503: }
504: }