33 import java.util.LinkedList; |
33 import java.util.LinkedList; |
34 import java.util.Iterator; |
34 import java.util.Iterator; |
35 import java.util.ListIterator; |
35 import java.util.ListIterator; |
36 import java.util.Set; |
36 import java.util.Set; |
37 |
37 |
38 import java.util.logging.Level; |
38 import sun.util.logging.PlatformLogger; |
39 import java.util.logging.Logger; |
|
40 |
39 |
41 import sun.awt.AppContext; |
40 import sun.awt.AppContext; |
42 import sun.awt.SunToolkit; |
41 import sun.awt.SunToolkit; |
43 import sun.awt.CausedFocusEvent; |
42 import sun.awt.CausedFocusEvent; |
44 |
43 |
60 * @see Component#setFocusTraversalKeys |
59 * @see Component#setFocusTraversalKeys |
61 * @see Component#getFocusTraversalKeys |
60 * @see Component#getFocusTraversalKeys |
62 * @since 1.4 |
61 * @since 1.4 |
63 */ |
62 */ |
64 public class DefaultKeyboardFocusManager extends KeyboardFocusManager { |
63 public class DefaultKeyboardFocusManager extends KeyboardFocusManager { |
65 private static final Logger focusLog = Logger.getLogger("java.awt.focus.DefaultKeyboardFocusManager"); |
64 private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.DefaultKeyboardFocusManager"); |
66 |
65 |
67 // null weak references to not create too many objects |
66 // null weak references to not create too many objects |
68 private static final WeakReference<Window> NULL_WINDOW_WR = |
67 private static final WeakReference<Window> NULL_WINDOW_WR = |
69 new WeakReference<Window>(null); |
68 new WeakReference<Window>(null); |
70 private static final WeakReference<Component> NULL_COMPONENT_WR = |
69 private static final WeakReference<Component> NULL_COMPONENT_WR = |
273 * @param e the AWTEvent to be dispatched |
272 * @param e the AWTEvent to be dispatched |
274 * @return <code>true</code> if this method dispatched the event; |
273 * @return <code>true</code> if this method dispatched the event; |
275 * <code>false</code> otherwise |
274 * <code>false</code> otherwise |
276 */ |
275 */ |
277 public boolean dispatchEvent(AWTEvent e) { |
276 public boolean dispatchEvent(AWTEvent e) { |
278 if (focusLog.isLoggable(Level.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e); |
277 if (focusLog.isLoggable(PlatformLogger.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e); |
279 switch (e.getID()) { |
278 switch (e.getID()) { |
280 case WindowEvent.WINDOW_GAINED_FOCUS: { |
279 case WindowEvent.WINDOW_GAINED_FOCUS: { |
281 WindowEvent we = (WindowEvent)e; |
280 WindowEvent we = (WindowEvent)e; |
282 Window oldFocusedWindow = getGlobalFocusedWindow(); |
281 Window oldFocusedWindow = getGlobalFocusedWindow(); |
283 Window newFocusedWindow = we.getWindow(); |
282 Window newFocusedWindow = we.getWindow(); |
376 tempLost = newFocusedWindow.setTemporaryLostComponent(null); |
375 tempLost = newFocusedWindow.setTemporaryLostComponent(null); |
377 } |
376 } |
378 |
377 |
379 // The component which last has the focus when this window was focused |
378 // The component which last has the focus when this window was focused |
380 // should receive focus first |
379 // should receive focus first |
381 if (focusLog.isLoggable(Level.FINER)) { |
380 if (focusLog.isLoggable(PlatformLogger.FINER)) { |
382 focusLog.log(Level.FINER, "tempLost {0}, toFocus {1}", |
381 focusLog.finer("tempLost {0}, toFocus {1}", |
383 new Object[]{tempLost, toFocus}); |
382 tempLost, toFocus); |
384 } |
383 } |
385 if (tempLost != null) { |
384 if (tempLost != null) { |
386 tempLost.requestFocusInWindow(CausedFocusEvent.Cause.ACTIVATION); |
385 tempLost.requestFocusInWindow(CausedFocusEvent.Cause.ACTIVATION); |
387 } |
386 } |
388 |
387 |
445 CausedFocusEvent.Cause cause = (fe instanceof CausedFocusEvent) ? |
444 CausedFocusEvent.Cause cause = (fe instanceof CausedFocusEvent) ? |
446 ((CausedFocusEvent)fe).getCause() : CausedFocusEvent.Cause.UNKNOWN; |
445 ((CausedFocusEvent)fe).getCause() : CausedFocusEvent.Cause.UNKNOWN; |
447 Component oldFocusOwner = getGlobalFocusOwner(); |
446 Component oldFocusOwner = getGlobalFocusOwner(); |
448 Component newFocusOwner = fe.getComponent(); |
447 Component newFocusOwner = fe.getComponent(); |
449 if (oldFocusOwner == newFocusOwner) { |
448 if (oldFocusOwner == newFocusOwner) { |
450 if (focusLog.isLoggable(Level.FINE)) { |
449 if (focusLog.isLoggable(PlatformLogger.FINE)) { |
451 focusLog.log(Level.FINE, "Skipping {0} because focus owner is the same", new Object[] {e}); |
450 focusLog.fine("Skipping {0} because focus owner is the same", e); |
452 } |
451 } |
453 // We can't just drop the event - there could be |
452 // We can't just drop the event - there could be |
454 // type-ahead markers associated with it. |
453 // type-ahead markers associated with it. |
455 dequeueKeyEvents(-1, newFocusOwner); |
454 dequeueKeyEvents(-1, newFocusOwner); |
456 break; |
455 break; |
563 |
562 |
564 case FocusEvent.FOCUS_LOST: { |
563 case FocusEvent.FOCUS_LOST: { |
565 FocusEvent fe = (FocusEvent)e; |
564 FocusEvent fe = (FocusEvent)e; |
566 Component currentFocusOwner = getGlobalFocusOwner(); |
565 Component currentFocusOwner = getGlobalFocusOwner(); |
567 if (currentFocusOwner == null) { |
566 if (currentFocusOwner == null) { |
568 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because focus owner is null", |
567 if (focusLog.isLoggable(PlatformLogger.FINE)) |
569 new Object[] {e}); |
568 focusLog.fine("Skipping {0} because focus owner is null", e); |
570 break; |
569 break; |
571 } |
570 } |
572 // Ignore cases where a Component loses focus to itself. |
571 // Ignore cases where a Component loses focus to itself. |
573 // If we make a mistake because of retargeting, then the |
572 // If we make a mistake because of retargeting, then the |
574 // FOCUS_GAINED handler will correct it. |
573 // FOCUS_GAINED handler will correct it. |
575 if (currentFocusOwner == fe.getOppositeComponent()) { |
574 if (currentFocusOwner == fe.getOppositeComponent()) { |
576 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because current focus owner is equal to opposite", |
575 if (focusLog.isLoggable(PlatformLogger.FINE)) |
577 new Object[] {e}); |
576 focusLog.fine("Skipping {0} because current focus owner is equal to opposite", e); |
578 break; |
577 break; |
579 } |
578 } |
580 |
579 |
581 setGlobalFocusOwner(null); |
580 setGlobalFocusOwner(null); |
582 |
581 |
640 WindowEvent we = (WindowEvent)e; |
639 WindowEvent we = (WindowEvent)e; |
641 Window currentFocusedWindow = getGlobalFocusedWindow(); |
640 Window currentFocusedWindow = getGlobalFocusedWindow(); |
642 Window losingFocusWindow = we.getWindow(); |
641 Window losingFocusWindow = we.getWindow(); |
643 Window activeWindow = getGlobalActiveWindow(); |
642 Window activeWindow = getGlobalActiveWindow(); |
644 Window oppositeWindow = we.getOppositeWindow(); |
643 Window oppositeWindow = we.getOppositeWindow(); |
645 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Active {0}, Current focused {1}, losing focus {2} opposite {3}", |
644 if (focusLog.isLoggable(PlatformLogger.FINE)) |
646 new Object[] {activeWindow, currentFocusedWindow, |
645 focusLog.fine("Active {0}, Current focused {1}, losing focus {2} opposite {3}", |
647 losingFocusWindow, oppositeWindow}); |
646 activeWindow, currentFocusedWindow, |
|
647 losingFocusWindow, oppositeWindow); |
648 if (currentFocusedWindow == null) { |
648 if (currentFocusedWindow == null) { |
649 break; |
649 break; |
650 } |
650 } |
651 |
651 |
652 // Special case -- if the native windowing system posts an |
652 // Special case -- if the native windowing system posts an |
841 |
841 |
842 /** |
842 /** |
843 * Dumps the list of type-ahead queue markers to stderr |
843 * Dumps the list of type-ahead queue markers to stderr |
844 */ |
844 */ |
845 void dumpMarkers() { |
845 void dumpMarkers() { |
846 if (focusLog.isLoggable(Level.FINEST)) { |
846 if (focusLog.isLoggable(PlatformLogger.FINEST)) { |
847 focusLog.log(Level.FINEST, ">>> Markers dump, time: {0}", System.currentTimeMillis()); |
847 focusLog.finest(">>> Markers dump, time: {0}", System.currentTimeMillis()); |
848 synchronized (this) { |
848 synchronized (this) { |
849 if (typeAheadMarkers.size() != 0) { |
849 if (typeAheadMarkers.size() != 0) { |
850 Iterator iter = typeAheadMarkers.iterator(); |
850 Iterator iter = typeAheadMarkers.iterator(); |
851 while (iter.hasNext()) { |
851 while (iter.hasNext()) { |
852 TypeAheadMarker marker = (TypeAheadMarker)iter.next(); |
852 TypeAheadMarker marker = (TypeAheadMarker)iter.next(); |
853 focusLog.log(Level.FINEST, " {0}", marker); |
853 focusLog.finest(" {0}", marker); |
854 } |
854 } |
855 } |
855 } |
856 } |
856 } |
857 } |
857 } |
858 } |
858 } |
876 // Fixed 5064013: may appears that the events have the same time |
876 // Fixed 5064013: may appears that the events have the same time |
877 // if (ke.getWhen() >= marker.after) { |
877 // if (ke.getWhen() >= marker.after) { |
878 // The fix is rolled out. |
878 // The fix is rolled out. |
879 |
879 |
880 if (ke.getWhen() > marker.after) { |
880 if (ke.getWhen() > marker.after) { |
881 focusLog.log(Level.FINER, "Storing event {0} because of marker {1}", new Object[] {ke, marker}); |
881 focusLog.finer("Storing event {0} because of marker {1}", ke, marker); |
882 enqueuedKeyEvents.addLast(ke); |
882 enqueuedKeyEvents.addLast(ke); |
883 return true; |
883 return true; |
884 } |
884 } |
885 } |
885 } |
886 } |
886 } |
888 // KeyEvent was posted before focus change request |
888 // KeyEvent was posted before focus change request |
889 return preDispatchKeyEvent(ke); |
889 return preDispatchKeyEvent(ke); |
890 } |
890 } |
891 |
891 |
892 case FocusEvent.FOCUS_GAINED: |
892 case FocusEvent.FOCUS_GAINED: |
893 focusLog.log(Level.FINEST, "Markers before FOCUS_GAINED on {0}", new Object[] {target}); |
893 focusLog.finest("Markers before FOCUS_GAINED on {0}", target); |
894 dumpMarkers(); |
894 dumpMarkers(); |
895 // Search the marker list for the first marker tied to |
895 // Search the marker list for the first marker tied to |
896 // the Component which just gained focus. Then remove |
896 // the Component which just gained focus. Then remove |
897 // that marker, any markers which immediately follow |
897 // that marker, any markers which immediately follow |
898 // and are tied to the same component, and all markers |
898 // and are tied to the same component, and all markers |
917 } |
917 } |
918 iter.remove(); |
918 iter.remove(); |
919 } |
919 } |
920 } else { |
920 } else { |
921 // Exception condition - event without marker |
921 // Exception condition - event without marker |
922 focusLog.log(Level.FINER, "Event without marker {0}", e); |
922 focusLog.finer("Event without marker {0}", e); |
923 } |
923 } |
924 } |
924 } |
925 focusLog.log(Level.FINEST, "Markers after FOCUS_GAINED"); |
925 focusLog.finest("Markers after FOCUS_GAINED"); |
926 dumpMarkers(); |
926 dumpMarkers(); |
927 |
927 |
928 redispatchEvent(target, e); |
928 redispatchEvent(target, e); |
929 |
929 |
930 // Now, dispatch any pending KeyEvents which have been |
930 // Now, dispatch any pending KeyEvents which have been |
1157 Component untilFocused) { |
1157 Component untilFocused) { |
1158 if (untilFocused == null) { |
1158 if (untilFocused == null) { |
1159 return; |
1159 return; |
1160 } |
1160 } |
1161 |
1161 |
1162 focusLog.log(Level.FINER, "Enqueue at {0} for {1}", |
1162 focusLog.finer("Enqueue at {0} for {1}", |
1163 new Object[] {after, untilFocused}); |
1163 after, untilFocused); |
1164 |
1164 |
1165 int insertionIndex = 0, |
1165 int insertionIndex = 0, |
1166 i = typeAheadMarkers.size(); |
1166 i = typeAheadMarkers.size(); |
1167 ListIterator iter = typeAheadMarkers.listIterator(i); |
1167 ListIterator iter = typeAheadMarkers.listIterator(i); |
1168 |
1168 |
1197 Component untilFocused) { |
1197 Component untilFocused) { |
1198 if (untilFocused == null) { |
1198 if (untilFocused == null) { |
1199 return; |
1199 return; |
1200 } |
1200 } |
1201 |
1201 |
1202 focusLog.log(Level.FINER, "Dequeue at {0} for {1}", |
1202 focusLog.finer("Dequeue at {0} for {1}", |
1203 new Object[] {after, untilFocused}); |
1203 after, untilFocused); |
1204 |
1204 |
1205 TypeAheadMarker marker; |
1205 TypeAheadMarker marker; |
1206 ListIterator iter = typeAheadMarkers.listIterator |
1206 ListIterator iter = typeAheadMarkers.listIterator |
1207 ((after >= 0) ? typeAheadMarkers.size() : 0); |
1207 ((after >= 0) ? typeAheadMarkers.size() : 0); |
1208 |
1208 |