292 Window toplevel = marker.untilFocused.getContainingWindow();
293 // Check that the component awaiting focus belongs to
294 // the current focused window. See 8015454.
295 if (toplevel != null && toplevel.isFocused()) {
296 SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
297 return true;
298 }
299 }
300 }
301 }
302 return false;
303 }
304
305 /**
306 * This method is called by the AWT event dispatcher requesting that the
307 * current KeyboardFocusManager dispatch the specified event on its behalf.
308 * DefaultKeyboardFocusManagers dispatch all FocusEvents, all WindowEvents
309 * related to focus, and all KeyEvents. These events are dispatched based
310 * on the KeyboardFocusManager's notion of the focus owner and the focused
311 * and active Windows, sometimes overriding the source of the specified
312 * AWTEvent. If this method returns <code>false</code>, then the AWT event
313 * dispatcher will attempt to dispatch the event itself.
314 *
315 * @param e the AWTEvent to be dispatched
316 * @return <code>true</code> if this method dispatched the event;
317 * <code>false</code> otherwise
318 */
319 public boolean dispatchEvent(AWTEvent e) {
320 if (focusLog.isLoggable(PlatformLogger.Level.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) {
321 focusLog.fine("" + e);
322 }
323 switch (e.getID()) {
324 case WindowEvent.WINDOW_GAINED_FOCUS: {
325 if (repostIfFollowsKeyEvents((WindowEvent)e)) {
326 break;
327 }
328
329 WindowEvent we = (WindowEvent)e;
330 Window oldFocusedWindow = getGlobalFocusedWindow();
331 Window newFocusedWindow = we.getWindow();
332 if (newFocusedWindow == oldFocusedWindow) {
333 break;
334 }
335
336 if (!(newFocusedWindow.isFocusableWindow()
337 && newFocusedWindow.isVisible()
761 // but possible.
762 restoreFocus(currentFocusedWindow, null, true);
763 }
764 }
765 break;
766 }
767
768 case KeyEvent.KEY_TYPED:
769 case KeyEvent.KEY_PRESSED:
770 case KeyEvent.KEY_RELEASED:
771 return typeAheadAssertions(null, e);
772
773 default:
774 return false;
775 }
776
777 return true;
778 }
779
780 /**
781 * Called by <code>dispatchEvent</code> if no other
782 * KeyEventDispatcher in the dispatcher chain dispatched the KeyEvent, or
783 * if no other KeyEventDispatchers are registered. If the event has not
784 * been consumed, its target is enabled, and the focus owner is not null,
785 * this method dispatches the event to its target. This method will also
786 * subsequently dispatch the event to all registered
787 * KeyEventPostProcessors. After all this operations are finished,
788 * the event is passed to peers for processing.
789 * <p>
790 * In all cases, this method returns <code>true</code>, since
791 * DefaultKeyboardFocusManager is designed so that neither
792 * <code>dispatchEvent</code>, nor the AWT event dispatcher, should take
793 * further action on the event in any situation.
794 *
795 * @param e the KeyEvent to be dispatched
796 * @return <code>true</code>
797 * @see Component#dispatchEvent
798 */
799 public boolean dispatchKeyEvent(KeyEvent e) {
800 Component focusOwner = (((AWTEvent)e).isPosted) ? getFocusOwner() : e.getComponent();
801
802 if (focusOwner != null && focusOwner.isShowing() && focusOwner.canBeFocusOwner()) {
803 if (!e.isConsumed()) {
804 Component comp = e.getComponent();
805 if (comp != null && comp.isEnabled()) {
806 redispatchEvent(comp, e);
807 }
808 }
809 }
810 boolean stopPostProcessing = false;
811 java.util.List<KeyEventPostProcessor> processors = getKeyEventPostProcessors();
812 if (processors != null) {
813 for (java.util.Iterator<KeyEventPostProcessor> iter = processors.iterator();
814 !stopPostProcessing && iter.hasNext(); )
815 {
816 stopPostProcessing = iter.next().
824 // Allow the peer to process KeyEvent
825 Component source = e.getComponent();
826 ComponentPeer peer = source.peer;
827
828 if (peer == null || peer instanceof LightweightPeer) {
829 // if focus owner is lightweight then its native container
830 // processes event
831 Container target = source.getNativeContainer();
832 if (target != null) {
833 peer = target.peer;
834 }
835 }
836 if (peer != null) {
837 peer.handleEvent(e);
838 }
839
840 return true;
841 }
842
843 /**
844 * This method will be called by <code>dispatchKeyEvent</code>. It will
845 * handle any unconsumed KeyEvents that map to an AWT
846 * <code>MenuShortcut</code> by consuming the event and activating the
847 * shortcut.
848 *
849 * @param e the KeyEvent to post-process
850 * @return <code>true</code>
851 * @see #dispatchKeyEvent
852 * @see MenuShortcut
853 */
854 public boolean postProcessKeyEvent(KeyEvent e) {
855 if (!e.isConsumed()) {
856 Component target = e.getComponent();
857 Container p = (Container)
858 (target instanceof Container ? target : target.getParent());
859 if (p != null) {
860 p.postProcessKeyEvent(e);
861 }
862 }
863 return true;
864 }
865
866 private void pumpApprovedKeyEvents() {
867 KeyEvent ke;
868 do {
869 ke = null;
870 synchronized (this) {
981 }
982 }
983 focusLog.finest("Markers after FOCUS_GAINED");
984 dumpMarkers();
985
986 redispatchEvent(target, e);
987
988 // Now, dispatch any pending KeyEvents which have been
989 // released because of the FOCUS_GAINED event so that we don't
990 // have to wait for another event to be posted to the queue.
991 pumpApprovedKeyEvents();
992 return true;
993
994 default:
995 redispatchEvent(target, e);
996 return true;
997 }
998 }
999
1000 /**
1001 * Returns true if there are some marker associated with component <code>comp</code>
1002 * in a markers' queue
1003 * @since 1.5
1004 */
1005 private boolean hasMarker(Component comp) {
1006 for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
1007 if (iter.next().untilFocused == comp) {
1008 return true;
1009 }
1010 }
1011 return false;
1012 }
1013
1014 /**
1015 * Clears markers queue
1016 * @since 1.5
1017 */
1018 void clearMarkers() {
1019 synchronized(this) {
1020 typeAheadMarkers.clear();
1021 }
1184
1185 toTest = focusedComponent.getFocusTraversalKeys(
1186 KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1187 contains = toTest.contains(stroke);
1188 containsOpp = toTest.contains(oppStroke);
1189
1190 if (contains || containsOpp) {
1191 consumeTraversalKey(e);
1192 if (contains) {
1193 downFocusCycle((Container)focusedComponent);
1194 }
1195 }
1196 }
1197 }
1198
1199 /**
1200 * Delays dispatching of KeyEvents until the specified Component becomes
1201 * the focus owner. KeyEvents with timestamps later than the specified
1202 * timestamp will be enqueued until the specified Component receives a
1203 * FOCUS_GAINED event, or the AWT cancels the delay request by invoking
1204 * <code>dequeueKeyEvents</code> or <code>discardKeyEvents</code>.
1205 *
1206 * @param after timestamp of current event, or the current, system time if
1207 * the current event has no timestamp, or the AWT cannot determine
1208 * which event is currently being handled
1209 * @param untilFocused Component which will receive a FOCUS_GAINED event
1210 * before any pending KeyEvents
1211 * @see #dequeueKeyEvents
1212 * @see #discardKeyEvents
1213 */
1214 protected synchronized void enqueueKeyEvents(long after,
1215 Component untilFocused) {
1216 if (untilFocused == null) {
1217 return;
1218 }
1219
1220 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
1221 focusLog.finer("Enqueue at {0} for {1}",
1222 after, untilFocused);
1223 }
1224
1225 int insertionIndex = 0,
1226 i = typeAheadMarkers.size();
1227 ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator(i);
1228
1229 for (; i > 0; i--) {
1230 TypeAheadMarker marker = iter.previous();
1231 if (marker.after <= after) {
1232 insertionIndex = i;
1233 break;
1234 }
1235 }
1236
1237 typeAheadMarkers.add(insertionIndex,
1238 new TypeAheadMarker(after, untilFocused));
1239 }
1240
1241 /**
1242 * Releases for normal dispatching to the current focus owner all
1243 * KeyEvents which were enqueued because of a call to
1244 * <code>enqueueKeyEvents</code> with the same timestamp and Component.
1245 * If the given timestamp is less than zero, the outstanding enqueue
1246 * request for the given Component with the <b>oldest</b> timestamp (if
1247 * any) should be cancelled.
1248 *
1249 * @param after the timestamp specified in the call to
1250 * <code>enqueueKeyEvents</code>, or any value < 0
1251 * @param untilFocused the Component specified in the call to
1252 * <code>enqueueKeyEvents</code>
1253 * @see #enqueueKeyEvents
1254 * @see #discardKeyEvents
1255 */
1256 protected synchronized void dequeueKeyEvents(long after,
1257 Component untilFocused) {
1258 if (untilFocused == null) {
1259 return;
1260 }
1261
1262 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
1263 focusLog.finer("Dequeue at {0} for {1}",
1264 after, untilFocused);
1265 }
1266
1267 TypeAheadMarker marker;
1268 ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator
1269 ((after >= 0) ? typeAheadMarkers.size() : 0);
1270
1271 if (after < 0) {
1272 while (iter.hasNext()) {
1275 {
1276 iter.remove();
1277 return;
1278 }
1279 }
1280 } else {
1281 while (iter.hasPrevious()) {
1282 marker = iter.previous();
1283 if (marker.untilFocused == untilFocused &&
1284 marker.after == after)
1285 {
1286 iter.remove();
1287 return;
1288 }
1289 }
1290 }
1291 }
1292
1293 /**
1294 * Discards all KeyEvents which were enqueued because of one or more calls
1295 * to <code>enqueueKeyEvents</code> with the specified Component, or one of
1296 * its descendants.
1297 *
1298 * @param comp the Component specified in one or more calls to
1299 * <code>enqueueKeyEvents</code>, or a parent of such a Component
1300 * @see #enqueueKeyEvents
1301 * @see #dequeueKeyEvents
1302 */
1303 protected synchronized void discardKeyEvents(Component comp) {
1304 if (comp == null) {
1305 return;
1306 }
1307
1308 long start = -1;
1309
1310 for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
1311 TypeAheadMarker marker = iter.next();
1312 Component toTest = marker.untilFocused;
1313 boolean match = (toTest == comp);
1314 while (!match && toTest != null && !(toTest instanceof Window)) {
1315 toTest = toTest.getParent();
1316 match = (toTest == comp);
1317 }
1318 if (match) {
1319 if (start < 0) {
|
292 Window toplevel = marker.untilFocused.getContainingWindow();
293 // Check that the component awaiting focus belongs to
294 // the current focused window. See 8015454.
295 if (toplevel != null && toplevel.isFocused()) {
296 SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
297 return true;
298 }
299 }
300 }
301 }
302 return false;
303 }
304
305 /**
306 * This method is called by the AWT event dispatcher requesting that the
307 * current KeyboardFocusManager dispatch the specified event on its behalf.
308 * DefaultKeyboardFocusManagers dispatch all FocusEvents, all WindowEvents
309 * related to focus, and all KeyEvents. These events are dispatched based
310 * on the KeyboardFocusManager's notion of the focus owner and the focused
311 * and active Windows, sometimes overriding the source of the specified
312 * AWTEvent. If this method returns {@code false}, then the AWT event
313 * dispatcher will attempt to dispatch the event itself.
314 *
315 * @param e the AWTEvent to be dispatched
316 * @return {@code true} if this method dispatched the event;
317 * {@code false} otherwise
318 */
319 public boolean dispatchEvent(AWTEvent e) {
320 if (focusLog.isLoggable(PlatformLogger.Level.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) {
321 focusLog.fine("" + e);
322 }
323 switch (e.getID()) {
324 case WindowEvent.WINDOW_GAINED_FOCUS: {
325 if (repostIfFollowsKeyEvents((WindowEvent)e)) {
326 break;
327 }
328
329 WindowEvent we = (WindowEvent)e;
330 Window oldFocusedWindow = getGlobalFocusedWindow();
331 Window newFocusedWindow = we.getWindow();
332 if (newFocusedWindow == oldFocusedWindow) {
333 break;
334 }
335
336 if (!(newFocusedWindow.isFocusableWindow()
337 && newFocusedWindow.isVisible()
761 // but possible.
762 restoreFocus(currentFocusedWindow, null, true);
763 }
764 }
765 break;
766 }
767
768 case KeyEvent.KEY_TYPED:
769 case KeyEvent.KEY_PRESSED:
770 case KeyEvent.KEY_RELEASED:
771 return typeAheadAssertions(null, e);
772
773 default:
774 return false;
775 }
776
777 return true;
778 }
779
780 /**
781 * Called by {@code dispatchEvent} if no other
782 * KeyEventDispatcher in the dispatcher chain dispatched the KeyEvent, or
783 * if no other KeyEventDispatchers are registered. If the event has not
784 * been consumed, its target is enabled, and the focus owner is not null,
785 * this method dispatches the event to its target. This method will also
786 * subsequently dispatch the event to all registered
787 * KeyEventPostProcessors. After all this operations are finished,
788 * the event is passed to peers for processing.
789 * <p>
790 * In all cases, this method returns {@code true}, since
791 * DefaultKeyboardFocusManager is designed so that neither
792 * {@code dispatchEvent}, nor the AWT event dispatcher, should take
793 * further action on the event in any situation.
794 *
795 * @param e the KeyEvent to be dispatched
796 * @return {@code true}
797 * @see Component#dispatchEvent
798 */
799 public boolean dispatchKeyEvent(KeyEvent e) {
800 Component focusOwner = (((AWTEvent)e).isPosted) ? getFocusOwner() : e.getComponent();
801
802 if (focusOwner != null && focusOwner.isShowing() && focusOwner.canBeFocusOwner()) {
803 if (!e.isConsumed()) {
804 Component comp = e.getComponent();
805 if (comp != null && comp.isEnabled()) {
806 redispatchEvent(comp, e);
807 }
808 }
809 }
810 boolean stopPostProcessing = false;
811 java.util.List<KeyEventPostProcessor> processors = getKeyEventPostProcessors();
812 if (processors != null) {
813 for (java.util.Iterator<KeyEventPostProcessor> iter = processors.iterator();
814 !stopPostProcessing && iter.hasNext(); )
815 {
816 stopPostProcessing = iter.next().
824 // Allow the peer to process KeyEvent
825 Component source = e.getComponent();
826 ComponentPeer peer = source.peer;
827
828 if (peer == null || peer instanceof LightweightPeer) {
829 // if focus owner is lightweight then its native container
830 // processes event
831 Container target = source.getNativeContainer();
832 if (target != null) {
833 peer = target.peer;
834 }
835 }
836 if (peer != null) {
837 peer.handleEvent(e);
838 }
839
840 return true;
841 }
842
843 /**
844 * This method will be called by {@code dispatchKeyEvent}. It will
845 * handle any unconsumed KeyEvents that map to an AWT
846 * {@code MenuShortcut} by consuming the event and activating the
847 * shortcut.
848 *
849 * @param e the KeyEvent to post-process
850 * @return {@code true}
851 * @see #dispatchKeyEvent
852 * @see MenuShortcut
853 */
854 public boolean postProcessKeyEvent(KeyEvent e) {
855 if (!e.isConsumed()) {
856 Component target = e.getComponent();
857 Container p = (Container)
858 (target instanceof Container ? target : target.getParent());
859 if (p != null) {
860 p.postProcessKeyEvent(e);
861 }
862 }
863 return true;
864 }
865
866 private void pumpApprovedKeyEvents() {
867 KeyEvent ke;
868 do {
869 ke = null;
870 synchronized (this) {
981 }
982 }
983 focusLog.finest("Markers after FOCUS_GAINED");
984 dumpMarkers();
985
986 redispatchEvent(target, e);
987
988 // Now, dispatch any pending KeyEvents which have been
989 // released because of the FOCUS_GAINED event so that we don't
990 // have to wait for another event to be posted to the queue.
991 pumpApprovedKeyEvents();
992 return true;
993
994 default:
995 redispatchEvent(target, e);
996 return true;
997 }
998 }
999
1000 /**
1001 * Returns true if there are some marker associated with component {@code comp}
1002 * in a markers' queue
1003 * @since 1.5
1004 */
1005 private boolean hasMarker(Component comp) {
1006 for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
1007 if (iter.next().untilFocused == comp) {
1008 return true;
1009 }
1010 }
1011 return false;
1012 }
1013
1014 /**
1015 * Clears markers queue
1016 * @since 1.5
1017 */
1018 void clearMarkers() {
1019 synchronized(this) {
1020 typeAheadMarkers.clear();
1021 }
1184
1185 toTest = focusedComponent.getFocusTraversalKeys(
1186 KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
1187 contains = toTest.contains(stroke);
1188 containsOpp = toTest.contains(oppStroke);
1189
1190 if (contains || containsOpp) {
1191 consumeTraversalKey(e);
1192 if (contains) {
1193 downFocusCycle((Container)focusedComponent);
1194 }
1195 }
1196 }
1197 }
1198
1199 /**
1200 * Delays dispatching of KeyEvents until the specified Component becomes
1201 * the focus owner. KeyEvents with timestamps later than the specified
1202 * timestamp will be enqueued until the specified Component receives a
1203 * FOCUS_GAINED event, or the AWT cancels the delay request by invoking
1204 * {@code dequeueKeyEvents} or {@code discardKeyEvents}.
1205 *
1206 * @param after timestamp of current event, or the current, system time if
1207 * the current event has no timestamp, or the AWT cannot determine
1208 * which event is currently being handled
1209 * @param untilFocused Component which will receive a FOCUS_GAINED event
1210 * before any pending KeyEvents
1211 * @see #dequeueKeyEvents
1212 * @see #discardKeyEvents
1213 */
1214 protected synchronized void enqueueKeyEvents(long after,
1215 Component untilFocused) {
1216 if (untilFocused == null) {
1217 return;
1218 }
1219
1220 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
1221 focusLog.finer("Enqueue at {0} for {1}",
1222 after, untilFocused);
1223 }
1224
1225 int insertionIndex = 0,
1226 i = typeAheadMarkers.size();
1227 ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator(i);
1228
1229 for (; i > 0; i--) {
1230 TypeAheadMarker marker = iter.previous();
1231 if (marker.after <= after) {
1232 insertionIndex = i;
1233 break;
1234 }
1235 }
1236
1237 typeAheadMarkers.add(insertionIndex,
1238 new TypeAheadMarker(after, untilFocused));
1239 }
1240
1241 /**
1242 * Releases for normal dispatching to the current focus owner all
1243 * KeyEvents which were enqueued because of a call to
1244 * {@code enqueueKeyEvents} with the same timestamp and Component.
1245 * If the given timestamp is less than zero, the outstanding enqueue
1246 * request for the given Component with the <b>oldest</b> timestamp (if
1247 * any) should be cancelled.
1248 *
1249 * @param after the timestamp specified in the call to
1250 * {@code enqueueKeyEvents}, or any value < 0
1251 * @param untilFocused the Component specified in the call to
1252 * {@code enqueueKeyEvents}
1253 * @see #enqueueKeyEvents
1254 * @see #discardKeyEvents
1255 */
1256 protected synchronized void dequeueKeyEvents(long after,
1257 Component untilFocused) {
1258 if (untilFocused == null) {
1259 return;
1260 }
1261
1262 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
1263 focusLog.finer("Dequeue at {0} for {1}",
1264 after, untilFocused);
1265 }
1266
1267 TypeAheadMarker marker;
1268 ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator
1269 ((after >= 0) ? typeAheadMarkers.size() : 0);
1270
1271 if (after < 0) {
1272 while (iter.hasNext()) {
1275 {
1276 iter.remove();
1277 return;
1278 }
1279 }
1280 } else {
1281 while (iter.hasPrevious()) {
1282 marker = iter.previous();
1283 if (marker.untilFocused == untilFocused &&
1284 marker.after == after)
1285 {
1286 iter.remove();
1287 return;
1288 }
1289 }
1290 }
1291 }
1292
1293 /**
1294 * Discards all KeyEvents which were enqueued because of one or more calls
1295 * to {@code enqueueKeyEvents} with the specified Component, or one of
1296 * its descendants.
1297 *
1298 * @param comp the Component specified in one or more calls to
1299 * {@code enqueueKeyEvents}, or a parent of such a Component
1300 * @see #enqueueKeyEvents
1301 * @see #dequeueKeyEvents
1302 */
1303 protected synchronized void discardKeyEvents(Component comp) {
1304 if (comp == null) {
1305 return;
1306 }
1307
1308 long start = -1;
1309
1310 for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
1311 TypeAheadMarker marker = iter.next();
1312 Component toTest = marker.untilFocused;
1313 boolean match = (toTest == comp);
1314 while (!match && toTest != null && !(toTest instanceof Window)) {
1315 toTest = toTest.getParent();
1316 match = (toTest == comp);
1317 }
1318 if (match) {
1319 if (start < 0) {
|