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 = getGlobalPermanentFocusOwner ();
278:
279: if (focusOwner != null)
280: redispatchEvent(focusOwner, e);
281:
282:
283:
284: Iterator i = getKeyEventPostProcessors().iterator();
285:
286: while (i.hasNext ())
287: {
288: KeyEventPostProcessor processor = (KeyEventPostProcessor) i.next ();
289: if (processor.postProcessKeyEvent ((KeyEvent) e))
290: return true;
291: }
292:
293:
294:
295: if (postProcessKeyEvent (e))
296: return true;
297:
298:
299: return true;
300: }
301:
302: public boolean postProcessKeyEvent (KeyEvent e)
303: {
304:
305:
306:
307: int modifiers = e.getModifiersEx ();
308: if (e.getID() == KeyEvent.KEY_PRESSED
309: && (modifiers & KeyEvent.CTRL_DOWN_MASK) != 0)
310: {
311: Window focusedWindow = getGlobalFocusedWindow ();
312: if (focusedWindow instanceof Frame)
313: {
314: MenuBar menubar = ((Frame) focusedWindow).getMenuBar ();
315:
316: if (menubar != null)
317: {
318:
319:
320:
321: int numMenus = menubar.getMenuCount ();
322:
323: for (int i = 0; i < numMenus; i++)
324: {
325: Menu menu = menubar.getMenu (i);
326: int numItems = menu.getItemCount ();
327:
328: for (int j = 0; j < numItems; j++)
329: {
330: MenuItem item = menu.getItem (j);
331: MenuShortcut shortcut = item.getShortcut ();
332:
333: if (item.isEnabled() && shortcut != null)
334: {
335:
336:
337:
338:
339:
340:
341:
342:
343: if (shortcut.getKey () == e.getKeyCode ()
344: && ((shortcut.usesShiftModifier ()
345: && (modifiers & KeyEvent.SHIFT_DOWN_MASK) != 0)
346: || (! shortcut.usesShiftModifier ()
347: && (modifiers & KeyEvent.SHIFT_DOWN_MASK) == 0)))
348: {
349: item.dispatchEvent (new ActionEvent (item,
350: ActionEvent.ACTION_PERFORMED,
351: item.getActionCommand (),
352: modifiers));
353:
354: return true;
355: }
356: }
357: }
358: }
359: }
360: }
361: }
362: return false;
363: }
364:
365: public void processKeyEvent (Component comp, KeyEvent e)
366: {
367: AWTKeyStroke eventKeystroke = AWTKeyStroke.getAWTKeyStrokeForEvent (e);
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379: AWTKeyStroke oppositeKeystroke = AWTKeyStroke.getAWTKeyStroke (e.getKeyCode (),
380: e.getModifiersEx (),
381: !(e.id == KeyEvent.KEY_RELEASED));
382:
383:
384:
385:
386:
387: if (waitForKeyStroke != null)
388: {
389: if (eventKeystroke.equals(waitForKeyStroke))
390:
391: waitForKeyStroke = null;
392:
393:
394:
395: e.consume();
396: return;
397: }
398:
399: Set forwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
400: Set backwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
401: Set upKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
402: Set downKeystrokes = null;
403: if (comp instanceof Container)
404: downKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
405:
406: if (forwardKeystrokes.contains (eventKeystroke))
407: {
408: waitForKeyStroke = oppositeKeystroke;
409: focusNextComponent (comp);
410: e.consume ();
411: }
412: else if (backwardKeystrokes.contains (eventKeystroke))
413: {
414: waitForKeyStroke = oppositeKeystroke;
415: focusPreviousComponent (comp);
416: e.consume ();
417: }
418: else if (upKeystrokes.contains (eventKeystroke))
419: {
420: waitForKeyStroke = oppositeKeystroke;
421: upFocusCycle (comp);
422: e.consume ();
423: }
424: else if (comp instanceof Container
425: && downKeystrokes.contains (eventKeystroke))
426: {
427: waitForKeyStroke = oppositeKeystroke;
428: downFocusCycle ((Container) comp);
429: e.consume ();
430: }
431: }
432:
433: protected void enqueueKeyEvents (long after, Component untilFocused)
434: {
435: delayRequests.add (new EventDelayRequest (after, untilFocused));
436: }
437:
438: protected void dequeueKeyEvents (long after, Component untilFocused)
439: {
440:
441:
442:
443:
444: if (after < 0)
445: {
446: int size = delayRequests.size ();
447: if (size > 0)
448: delayRequests.remove (delayRequests.first ());
449: }
450: else
451: {
452: EventDelayRequest template = new EventDelayRequest (after, untilFocused);
453: if (delayRequests.contains (template))
454: {
455: EventDelayRequest actual = (EventDelayRequest) delayRequests.tailSet (template).first ();
456: delayRequests.remove (actual);
457: actual.dispatchEvents ();
458: }
459: }
460: }
461:
462: protected void discardKeyEvents (Component comp)
463: {
464:
465:
466: Iterator i = delayRequests.iterator ();
467:
468: while (i.hasNext ())
469: {
470: EventDelayRequest request = (EventDelayRequest) i.next ();
471:
472: if (request.focusedComp == comp
473: || (comp instanceof Container
474: && ((Container) comp).isAncestorOf (request.focusedComp)))
475: request.discardEvents ();
476: }
477: }
478:
479: public void focusPreviousComponent (Component comp)
480: {
481: Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
482: Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
483: FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
484:
485: Component previous = policy.getComponentBefore (focusCycleRoot, focusComp);
486: if (previous != null)
487: previous.requestFocusInWindow ();
488: }
489:
490: public void focusNextComponent (Component comp)
491: {
492: Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
493: Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
494: FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
495:
496: Component next = policy.getComponentAfter (focusCycleRoot, focusComp);
497: if (next != null)
498: next.requestFocusInWindow ();
499: }
500:
501: public void upFocusCycle (Component comp)
502: {
503: Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
504: Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
505:
506: if (focusCycleRoot instanceof Window)
507: {
508: FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
509: Component defaultComponent = policy.getDefaultComponent (focusCycleRoot);
510: if (defaultComponent != null)
511: defaultComponent.requestFocusInWindow ();
512: }
513: else
514: {
515: Container parentFocusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor ();
516:
517: focusCycleRoot.requestFocusInWindow ();
518: setGlobalCurrentFocusCycleRoot (parentFocusCycleRoot);
519: }
520: }
521:
522: public void downFocusCycle (Container cont)
523: {
524: if (cont == null)
525: return;
526:
527: if (cont.isFocusCycleRoot (cont))
528: {
529: FocusTraversalPolicy policy = cont.getFocusTraversalPolicy ();
530: Component defaultComponent = policy.getDefaultComponent (cont);
531: if (defaultComponent != null)
532: defaultComponent.requestFocusInWindow ();
533: setGlobalCurrentFocusCycleRoot (cont);
534: }
535: }
536: }