| 1 7 package java.awt; 8 9 import java.awt.event.FocusEvent ; 10 import java.awt.event.KeyEvent ; 11 import java.awt.event.WindowEvent ; 12 import java.awt.peer.ComponentPeer; 13 import java.awt.peer.LightweightPeer; 14 import java.beans.PropertyChangeListener ; 15 import java.util.LinkedList ; 16 import java.util.Iterator ; 17 import java.util.ListIterator ; 18 import java.util.Set ; 19 20 import java.util.logging.*; 21 22 import sun.awt.AppContext; 23 import sun.awt.SunToolkit; 24 25 45 public class DefaultKeyboardFocusManager extends KeyboardFocusManager { 46 private static final Logger focusLog = Logger.getLogger("java.awt.focus.DefaultKeyboardFocusManager"); 47 48 private Window realOppositeWindow; 49 private Component realOppositeComponent; 50 private int inSendMessage; 51 private LinkedList enqueuedKeyEvents = new LinkedList (), 52 typeAheadMarkers = new LinkedList (); 53 private boolean consumeNextKeyTyped; 54 55 private static class TypeAheadMarker { 56 long after; 57 Component untilFocused; 58 59 TypeAheadMarker(long after, Component untilFocused) { 60 this.after = after; 61 this.untilFocused = untilFocused; 62 } 63 66 public String toString() { 67 return ">>> Marker after " + after + " on " + untilFocused; 68 } 69 } 70 71 private Window getOwningFrameDialog(Window window) { 72 while (window != null && !(window instanceof Frame || 73 window instanceof Dialog )) { 74 window = (Window )window.getParent(); 75 } 76 return window; 77 } 78 79 84 private void restoreFocus(FocusEvent fe, Window newFocusedWindow) { 85 Component realOppositeComponent = this.realOppositeComponent; 86 Component vetoedComponent = fe.getComponent(); 87 if (newFocusedWindow != null && restoreFocus(newFocusedWindow, 88 vetoedComponent, false)) 89 { 90 } else if (realOppositeComponent != null && 91 restoreFocus(realOppositeComponent, false)) { 92 } else if (fe.getOppositeComponent() != null && 93 restoreFocus(fe.getOppositeComponent(), false)) { 94 } else { 95 clearGlobalFocusOwner(); 96 } 97 } 98 private void restoreFocus(WindowEvent we) { 99 Window realOppositeWindow = this.realOppositeWindow; 100 if (realOppositeWindow != null && restoreFocus(realOppositeWindow, 101 null, false)) { 102 } else if (we.getOppositeWindow() != null && 103 restoreFocus(we.getOppositeWindow(), null, false)) { 104 } else { 105 clearGlobalFocusOwner(); 106 } 107 } 108 private boolean restoreFocus(Window aWindow, Component vetoedComponent, 109 boolean clearOnFailure) { 110 Component toFocus = 111 KeyboardFocusManager.getMostRecentFocusOwner(aWindow); 112 if (toFocus != null && toFocus != vetoedComponent && restoreFocus(toFocus, false)) { 113 return true; 114 } else if (clearOnFailure) { 115 clearGlobalFocusOwner(); 116 return true; 117 } else { 118 return false; 119 } 120 } 121 private boolean restoreFocus(Component toFocus, boolean clearOnFailure) { 122 if (toFocus.isShowing() && toFocus.isFocusable() && 123 toFocus.requestFocus(false)) { 124 return true; 125 } else if (toFocus.nextFocusHelper()) { 126 return true; 127 } else if (clearOnFailure) { 128 clearGlobalFocusOwner(); 129 return true; 130 } else { 131 return false; 132 } 133 } 134 135 140 private static class DefaultKeyboardFocusManagerSentEvent 141 extends SentEvent  142 { 143 public DefaultKeyboardFocusManagerSentEvent(AWTEvent nested, 144 AppContext toNotify) { 145 super(nested, toNotify); 146 } 147 public final void dispatch() { 148 KeyboardFocusManager manager = 149 KeyboardFocusManager.getCurrentKeyboardFocusManager(); 150 DefaultKeyboardFocusManager defaultManager = 151 (manager instanceof DefaultKeyboardFocusManager ) 152 ? (DefaultKeyboardFocusManager )manager 153 : null; 154 155 if (defaultManager != null) { 156 synchronized (defaultManager) { 157 defaultManager.inSendMessage++; 158 } 159 } 160 161 super.dispatch(); 162 163 if (defaultManager != null) { 164 synchronized (defaultManager) { 165 defaultManager.inSendMessage--; 166 } 167 } 168 } 169 } 170 171 180 static boolean sendMessage(Component target, AWTEvent e) { 181 e.isPosted = true; 182 AppContext myAppContext = AppContext.getAppContext(); 183 final AppContext targetAppContext = target.appContext; 184 final SentEvent se = 185 new DefaultKeyboardFocusManagerSentEvent(e, myAppContext); 186 187 if (myAppContext == targetAppContext) { 188 se.dispatch(); 189 } else { 190 if (targetAppContext.isDisposed()) { 191 return false; 192 } 193 SunToolkit.postEvent(targetAppContext, se); 194 if (EventQueue.isDispatchThread()) { 195 EventDispatchThread edt = (EventDispatchThread ) 196 Thread.currentThread(); 197 edt.pumpEvents(SentEvent.ID, new Conditional () { 198 public boolean evaluate() { 199 return !se.dispatched && !targetAppContext.isDisposed(); 200 } 201 }); 202 } else { 203 synchronized (se) { 204 while (!se.dispatched && !targetAppContext.isDisposed()) { 205 try { 206 se.wait(1000); 207 } catch (InterruptedException ie) { 208 break; 209 } 210 } 211 } 212 } 213 } 214 return se.dispatched; 215 } 216 217 231 public boolean dispatchEvent(AWTEvent e) { 232 if (focusLog.isLoggable(Level.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent )) focusLog.fine("" + e); 233 switch (e.getID()) { 234 case WindowEvent.WINDOW_GAINED_FOCUS: { 235 WindowEvent we = (WindowEvent )e; 236 Window oldFocusedWindow = getGlobalFocusedWindow(); 237 Window newFocusedWindow = we.getWindow(); 238 if (newFocusedWindow == oldFocusedWindow) { 239 break; 240 } 241 242 if (oldFocusedWindow != null) { 245 boolean isEventDispatched = 246 sendMessage(oldFocusedWindow, 247 new WindowEvent (oldFocusedWindow, 248 WindowEvent.WINDOW_LOST_FOCUS, 249 newFocusedWindow)); 250 if (!isEventDispatched) { 252 setGlobalFocusOwner(null); 253 setGlobalFocusedWindow(null); 254 } 255 } 256 257 Window newActiveWindow = 261 getOwningFrameDialog(newFocusedWindow); 262 Window currentActiveWindow = getGlobalActiveWindow(); 263 if (newActiveWindow != currentActiveWindow) { 264 sendMessage(newActiveWindow, 265 new WindowEvent (newActiveWindow, 266 WindowEvent.WINDOW_ACTIVATED, 267 currentActiveWindow)); 268 if (newActiveWindow != getGlobalActiveWindow()) { 269 restoreFocus(we); 272 break; 273 } 274 } 275 276 setGlobalFocusedWindow(newFocusedWindow); 277 278 if (newFocusedWindow != getGlobalFocusedWindow()) { 279 restoreFocus(we); 282 break; 283 } 284 285 setNativeFocusedWindow(newFocusedWindow); 286 if (inSendMessage == 0) { 294 306 307 Component toFocus = KeyboardFocusManager. 314 getMostRecentFocusOwner(newFocusedWindow); 315 if ((toFocus == null) && 316 newFocusedWindow.isFocusableWindow()) 317 { 318 toFocus = newFocusedWindow.getFocusTraversalPolicy(). 319 getInitialComponent(newFocusedWindow); 320 } 321 Component tempLost = null; 322 synchronized(KeyboardFocusManager .class) { 323 tempLost = newFocusedWindow.setTemporaryLostComponent(null); 324 } 325 326 if (focusLog.isLoggable(Level.FINER)) { 329 focusLog.log(Level.FINER, "tempLost {0}, toFocus {1}", 330 new Object []{tempLost, toFocus}); 331 } 332 setInActivation(true); 333 if (tempLost != null) { 334 tempLost.requestFocusInWindow(); 335 } 336 337 if (toFocus != null && toFocus != tempLost) { 338 toFocus.requestFocusInWindow(); 341 } 342 setInActivation(false); 343 } 344 345 Window realOppositeWindow = this.realOppositeWindow; 346 if (realOppositeWindow != we.getOppositeWindow()) { 347 we = new WindowEvent (newFocusedWindow, 348 WindowEvent.WINDOW_GAINED_FOCUS, 349 realOppositeWindow); 350 } 351 return typeAheadAssertions(newFocusedWindow, we); 352 } 353 354 case WindowEvent.WINDOW_ACTIVATED: { 355 WindowEvent we = (WindowEvent )e; 356 Window oldActiveWindow = getGlobalActiveWindow(); 357 Window newActiveWindow = we.getWindow(); 358 if (oldActiveWindow == newActiveWindow) { 359 break; 360 } 361 362 if (oldActiveWindow != null) { 365 boolean isEventDispatched = 366 sendMessage(oldActiveWindow, 367 new WindowEvent (oldActiveWindow, 368 WindowEvent.WINDOW_DEACTIVATED, 369 newActiveWindow)); 370 if (!isEventDispatched) { 372 setGlobalActiveWindow(null); 373 } 374 if (getGlobalActiveWindow() != null) { 375 break; 378 } 379 } 380 381 setGlobalActiveWindow(newActiveWindow); 382 383 if (newActiveWindow != getGlobalActiveWindow()) { 384 break; 387 } 388 389 return typeAheadAssertions(newActiveWindow, we); 390 } 391 392 case FocusEvent.FOCUS_GAINED: { 393 FocusEvent fe = (FocusEvent )e; 394 Component oldFocusOwner = getGlobalFocusOwner(); 395 Component newFocusOwner = fe.getComponent(); 396 if (oldFocusOwner == newFocusOwner) { 397 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because focus owner is the same", 398 new Object [] {e}); 399 dequeueKeyEvents(-1, newFocusOwner); 402 break; 403 } 404 405 if (oldFocusOwner != null) { 408 boolean isEventDispatched = 409 sendMessage(oldFocusOwner, 410 new FocusEvent (oldFocusOwner, 411 FocusEvent.FOCUS_LOST, 412 fe.isTemporary(), 413 newFocusOwner)); 414 if (!isEventDispatched) { 416 setGlobalFocusOwner(null); 417 if (!fe.isTemporary()) { 418 setGlobalPermanentFocusOwner(null); 419 } 420 } 421 } 422 423 Component newFocusedWindow = newFocusOwner; 429 while (newFocusedWindow != null && 430 !(newFocusedWindow instanceof Window )) { 431 newFocusedWindow = newFocusedWindow.parent; 432 } 433 Window currentFocusedWindow = getGlobalFocusedWindow(); 434 if (newFocusedWindow != null && 435 newFocusedWindow != currentFocusedWindow) 436 { 437 sendMessage(newFocusedWindow, 438 new WindowEvent ((Window )newFocusedWindow, 439 WindowEvent.WINDOW_GAINED_FOCUS, 440 currentFocusedWindow)); 441 if (newFocusedWindow != getGlobalFocusedWindow()) { 442 445 dequeueKeyEvents(-1, newFocusOwner); 449 break; 450 } 451 } 452 453 setGlobalFocusOwner(newFocusOwner); 454 455 if (newFocusOwner != getGlobalFocusOwner()) { 456 dequeueKeyEvents(-1, newFocusOwner); 459 if (! disableRestoreFocus ){ 460 restoreFocus(fe, (Window )newFocusedWindow); 461 } 462 break; 463 } 464 465 if (!fe.isTemporary()) { 466 setGlobalPermanentFocusOwner(newFocusOwner); 467 468 if (newFocusOwner != getGlobalPermanentFocusOwner()) { 469 dequeueKeyEvents(-1, newFocusOwner); 471 if (! disableRestoreFocus ){ 472 restoreFocus(fe, (Window )newFocusedWindow); 473 } 474 break; 475 } 476 } 477 478 setNativeFocusOwner(getHeavyweight(newFocusOwner)); 479 480 Component realOppositeComponent = this.realOppositeComponent; 481 if (realOppositeComponent != null && 482 realOppositeComponent != fe.getOppositeComponent()) { 483 fe = new FocusEvent (newFocusOwner, 484 FocusEvent.FOCUS_GAINED, 485 fe.isTemporary(), 486 realOppositeComponent); 487 ((AWTEvent ) fe).isPosted = true; 488 } 489 return typeAheadAssertions(newFocusOwner, fe); 490 } 491 492 case FocusEvent.FOCUS_LOST: { 493 FocusEvent fe = (FocusEvent )e; 494 Component currentFocusOwner = getGlobalFocusOwner(); 495 if (currentFocusOwner == null) { 496 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because focus owner is null", 497 new Object [] {e}); 498 break; 499 } 500 if (currentFocusOwner == fe.getOppositeComponent()) { 504 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Skipping {0} because current focus owner is equal to opposite", 505 new Object [] {e}); 506 break; 507 } 508 509 setGlobalFocusOwner(null); 510 511 if (getGlobalFocusOwner() != null) { 512 restoreFocus(currentFocusOwner, true); 514 break; 515 } 516 517 if (!fe.isTemporary()) { 518 setGlobalPermanentFocusOwner(null); 519 520 if (getGlobalPermanentFocusOwner() != null) { 521 restoreFocus(currentFocusOwner, true); 523 break; 524 } 525 } else { 526 Window owningWindow = currentFocusOwner.getContainingWindow(); 527 if (owningWindow != null) { 528 owningWindow.setTemporaryLostComponent(currentFocusOwner); 529 } 530 } 531 532 setNativeFocusOwner(null); 533 534 fe.setSource(currentFocusOwner); 535 536 realOppositeComponent = (fe.getOppositeComponent() != null) 537 ? currentFocusOwner : null; 538 539 return typeAheadAssertions(currentFocusOwner, fe); 540 } 541 542 case WindowEvent.WINDOW_DEACTIVATED: { 543 WindowEvent we = (WindowEvent )e; 544 Window currentActiveWindow = getGlobalActiveWindow(); 545 if (currentActiveWindow == null) { 546 break; 547 } 548 549 if (currentActiveWindow != e.getSource()) { 550 break; 554 } 555 556 setGlobalActiveWindow(null); 557 if (getGlobalActiveWindow() != null) { 558 break; 560 } 561 562 we.setSource(currentActiveWindow); 563 return typeAheadAssertions(currentActiveWindow, we); 564 } 565 566 case WindowEvent.WINDOW_LOST_FOCUS: { 567 WindowEvent we = (WindowEvent )e; 568 Window currentFocusedWindow = getGlobalFocusedWindow(); 569 Window losingFocusWindow = we.getWindow(); 570 Window activeWindow = getGlobalActiveWindow(); 571 Window oppositeWindow = we.getOppositeWindow(); 572 if (focusLog.isLoggable(Level.FINE)) focusLog.log(Level.FINE, "Active {0}, Current focused {1}, losing focus {2} opposite {3}", 573 new Object [] {activeWindow, currentFocusedWindow, 574 losingFocusWindow, oppositeWindow}); 575 if (currentFocusedWindow == null) { 576 break; 577 } 578 579 if (inSendMessage == 0 && losingFocusWindow == activeWindow && 585 oppositeWindow == currentFocusedWindow) 586 { 587 break; 588 } 589 590 Component currentFocusOwner = getGlobalFocusOwner(); 591 if (currentFocusOwner != null) { 592 Component oppositeComp = null; 595 if (oppositeWindow != null) { 596 oppositeComp = oppositeWindow.getTemporaryLostComponent(); 597 if (oppositeComp == null) { 598 oppositeComp = oppositeWindow.getMostRecentFocusOwner(); 599 } 600 } 601 if (oppositeComp == null) { 602 oppositeComp = oppositeWindow; 603 } 604 sendMessage(currentFocusOwner, 605 new FocusEvent (currentFocusOwner, 606 FocusEvent.FOCUS_LOST, 607 true, 608 oppositeComp)); 609 } 610 611 setGlobalFocusedWindow(null); 612 if (getGlobalFocusedWindow() != null) { 613 restoreFocus(currentFocusedWindow, null, true); 615 break; 616 } 617 setNativeFocusedWindow(null); 618 619 we.setSource(currentFocusedWindow); 620 realOppositeWindow = (oppositeWindow != null) 621 ? currentFocusedWindow 622 : null; 623 typeAheadAssertions(currentFocusedWindow, we); 624 625 if (oppositeWindow == null) { 626 sendMessage(activeWindow, 630 new WindowEvent (activeWindow, 631 WindowEvent.WINDOW_DEACTIVATED, 632 null)); 633 if (getGlobalActiveWindow() != null) { 634 restoreFocus(currentFocusedWindow, null, true); 637 } 638 } 639 break; 640 } 641 642 case KeyEvent.KEY_TYPED: 643 case KeyEvent.KEY_PRESSED: 644 case KeyEvent.KEY_RELEASED: 645 return typeAheadAssertions(null, e); 646 647 default: 648 return false; 649 } 650 651 return true; 652 } 653 654 |