< prev index next >

src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java

Print this page




  58  *
  59  * @see FocusTraversalPolicy
  60  * @see Component#setFocusTraversalKeys
  61  * @see Component#getFocusTraversalKeys
  62  * @since 1.4
  63  */
  64 public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
  65     private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.DefaultKeyboardFocusManager");
  66 
  67     // null weak references to not create too many objects
  68     private static final WeakReference<Window> NULL_WINDOW_WR =
  69         new WeakReference<Window>(null);
  70     private static final WeakReference<Component> NULL_COMPONENT_WR =
  71         new WeakReference<Component>(null);
  72     private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR;
  73     private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
  74     private int inSendMessage;
  75     private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
  76     private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
  77     private boolean consumeNextKeyTyped;

  78 
  79     static {
  80         AWTAccessor.setDefaultKeyboardFocusManagerAccessor(
  81             new AWTAccessor.DefaultKeyboardFocusManagerAccessor() {
  82                 public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e) {
  83                     dkfm.consumeNextKeyTyped(e);
  84                 }
  85             });
  86     }
  87 
  88     private static class TypeAheadMarker {
  89         long after;
  90         Component untilFocused;
  91 
  92         TypeAheadMarker(long after, Component untilFocused) {
  93             this.after = after;
  94             this.untilFocused = untilFocused;
  95         }
  96         /**
  97          * Returns string representation of the marker


 128         } else {
 129             clearGlobalFocusOwnerPriv();
 130         }
 131     }
 132     private void restoreFocus(WindowEvent we) {
 133         Window realOppositeWindow = this.realOppositeWindowWR.get();
 134         if (realOppositeWindow != null
 135             && restoreFocus(realOppositeWindow, null, false))
 136         {
 137             // do nothing, everything is done in restoreFocus()
 138         } else if (we.getOppositeWindow() != null &&
 139                    restoreFocus(we.getOppositeWindow(), null, false))
 140         {
 141             // do nothing, everything is done in restoreFocus()
 142         } else {
 143             clearGlobalFocusOwnerPriv();
 144         }
 145     }
 146     private boolean restoreFocus(Window aWindow, Component vetoedComponent,
 147                                  boolean clearOnFailure) {

 148         Component toFocus =
 149             KeyboardFocusManager.getMostRecentFocusOwner(aWindow);
 150 
 151         if (toFocus != null && toFocus != vetoedComponent) {
 152             Component heavyweight = getHeavyweight(aWindow);
 153             if (heavyweight != null) {
 154                 setNativeFocusOwner(heavyweight);
 155                 Toolkit.getEventQueue().createSecondaryLoop(
 156                         () -> getGlobalFocusedWindow() != aWindow, null, 50)
 157                         .enter();
 158             }
 159             if (getGlobalFocusedWindow() == aWindow &&
 160                               doRestoreFocus(toFocus, vetoedComponent, false)) {






 161                 return true;
 162             }
 163         }
 164         if (clearOnFailure) {
 165             clearGlobalFocusOwnerPriv();
 166             return true;
 167         } else {
 168             return false;
 169         }
 170     }
 171     private boolean restoreFocus(Component toFocus, boolean clearOnFailure) {
 172         return doRestoreFocus(toFocus, null, clearOnFailure);
 173     }
 174     private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
 175                                    boolean clearOnFailure)
 176     {
 177         if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.canBeFocusOwner() &&
 178             toFocus.requestFocus(false, FocusEvent.Cause.ROLLBACK))
 179         {
 180             return true;


 406                     // in the Window.
 407                     //
 408                     // * If we're in SendMessage, then this is a synthetic
 409                     //   WINDOW_GAINED_FOCUS message which was generated by a
 410                     //   the FOCUS_GAINED handler. Allow the Component to
 411                     //   which the FOCUS_GAINED message was targeted to
 412                     //   receive the focus.
 413                     // * Otherwise, look up the correct Component here.
 414                     //   We don't use Window.getMostRecentFocusOwner because
 415                     //   window is focused now and 'null' will be returned
 416 
 417 
 418                     // Calculating of most recent focus owner and focus
 419                     // request should be synchronized on KeyboardFocusManager.class
 420                     // to prevent from thread race when user will request
 421                     // focus between calculation and our request.
 422                     // But if focus transfer is synchronous, this synchronization
 423                     // may cause deadlock, thus we don't synchronize this block.
 424                     Component toFocus = KeyboardFocusManager.
 425                         getMostRecentFocusOwner(newFocusedWindow);


 426                     if ((toFocus == null) &&
 427                         newFocusedWindow.isFocusableWindow())
 428                     {
 429                         toFocus = newFocusedWindow.getFocusTraversalPolicy().
 430                             getInitialComponent(newFocusedWindow);
 431                     }
 432                     Component tempLost = null;
 433                     synchronized(KeyboardFocusManager.class) {
 434                         tempLost = newFocusedWindow.setTemporaryLostComponent(null);
 435                     }
 436 
 437                     // The component which last has the focus when this window was focused
 438                     // should receive focus first
 439                     if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
 440                         focusLog.finer("tempLost {0}, toFocus {1}",
 441                                        tempLost, toFocus);
 442                     }
 443                     if (tempLost != null) {
 444                         tempLost.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);


 445                     }
 446 
 447                     if (toFocus != null && toFocus != tempLost) {
 448                         // If there is a component which requested focus when this window
 449                         // was inactive it expects to receive focus after activation.
 450                         toFocus.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);
 451                     }
 452                 }

 453 
 454                 Window realOppositeWindow = this.realOppositeWindowWR.get();
 455                 if (realOppositeWindow != we.getOppositeWindow()) {
 456                     we = new WindowEvent(newFocusedWindow,
 457                                          WindowEvent.WINDOW_GAINED_FOCUS,
 458                                          realOppositeWindow);
 459                 }
 460                 return typeAheadAssertions(newFocusedWindow, we);
 461             }
 462 
 463             case WindowEvent.WINDOW_ACTIVATED: {
 464                 WindowEvent we = (WindowEvent)e;
 465                 Window oldActiveWindow = getGlobalActiveWindow();
 466                 Window newActiveWindow = we.getWindow();
 467                 if (oldActiveWindow == newActiveWindow) {
 468                     break;
 469                 }
 470 
 471                 // If there exists a current active window, then notify it that
 472                 // it has lost activation.


 482                     }
 483                     if (getGlobalActiveWindow() != null) {
 484                         // Activation change was rejected. Unlikely, but
 485                         // possible.
 486                         break;
 487                     }
 488                 }
 489 
 490                 setGlobalActiveWindow(newActiveWindow);
 491 
 492                 if (newActiveWindow != getGlobalActiveWindow()) {
 493                     // Activation change was rejected. Unlikely, but
 494                     // possible.
 495                     break;
 496                 }
 497 
 498                 return typeAheadAssertions(newActiveWindow, we);
 499             }
 500 
 501             case FocusEvent.FOCUS_GAINED: {

 502                 FocusEvent fe = (FocusEvent)e;
 503                 Component oldFocusOwner = getGlobalFocusOwner();
 504                 Component newFocusOwner = fe.getComponent();
 505                 if (oldFocusOwner == newFocusOwner) {
 506                     if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
 507                         focusLog.fine("Skipping {0} because focus owner is the same", e);
 508                     }
 509                     // We can't just drop the event - there could be
 510                     // type-ahead markers associated with it.
 511                     dequeueKeyEvents(-1, newFocusOwner);
 512                     break;
 513                 }
 514 
 515                 // If there exists a current focus owner, then notify it that
 516                 // it has lost focus.
 517                 if (oldFocusOwner != null) {
 518                     boolean isEventDispatched =
 519                         sendMessage(oldFocusOwner,
 520                                     new FocusEvent(oldFocusOwner,
 521                                                    FocusEvent.FOCUS_LOST,




  58  *
  59  * @see FocusTraversalPolicy
  60  * @see Component#setFocusTraversalKeys
  61  * @see Component#getFocusTraversalKeys
  62  * @since 1.4
  63  */
  64 public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
  65     private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.DefaultKeyboardFocusManager");
  66 
  67     // null weak references to not create too many objects
  68     private static final WeakReference<Window> NULL_WINDOW_WR =
  69         new WeakReference<Window>(null);
  70     private static final WeakReference<Component> NULL_COMPONENT_WR =
  71         new WeakReference<Component>(null);
  72     private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR;
  73     private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
  74     private int inSendMessage;
  75     private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
  76     private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
  77     private boolean consumeNextKeyTyped;
  78     private Component restoreFocusTo;
  79 
  80     static {
  81         AWTAccessor.setDefaultKeyboardFocusManagerAccessor(
  82             new AWTAccessor.DefaultKeyboardFocusManagerAccessor() {
  83                 public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e) {
  84                     dkfm.consumeNextKeyTyped(e);
  85                 }
  86             });
  87     }
  88 
  89     private static class TypeAheadMarker {
  90         long after;
  91         Component untilFocused;
  92 
  93         TypeAheadMarker(long after, Component untilFocused) {
  94             this.after = after;
  95             this.untilFocused = untilFocused;
  96         }
  97         /**
  98          * Returns string representation of the marker


 129         } else {
 130             clearGlobalFocusOwnerPriv();
 131         }
 132     }
 133     private void restoreFocus(WindowEvent we) {
 134         Window realOppositeWindow = this.realOppositeWindowWR.get();
 135         if (realOppositeWindow != null
 136             && restoreFocus(realOppositeWindow, null, false))
 137         {
 138             // do nothing, everything is done in restoreFocus()
 139         } else if (we.getOppositeWindow() != null &&
 140                    restoreFocus(we.getOppositeWindow(), null, false))
 141         {
 142             // do nothing, everything is done in restoreFocus()
 143         } else {
 144             clearGlobalFocusOwnerPriv();
 145         }
 146     }
 147     private boolean restoreFocus(Window aWindow, Component vetoedComponent,
 148                                  boolean clearOnFailure) {
 149         restoreFocusTo = null;
 150         Component toFocus =
 151             KeyboardFocusManager.getMostRecentFocusOwner(aWindow);
 152 
 153         if (toFocus != null && toFocus != vetoedComponent) {
 154             if (getHeavyweight(aWindow) != getNativeFocusOwner()) {
 155                 // cannot restore focus synchronously
 156                 if (!toFocus.isShowing() || !toFocus.canBeFocusOwner()) {
 157                     toFocus = toFocus.getNextFocusCandidate();


 158                 }
 159                 if (toFocus != null && toFocus != vetoedComponent) {
 160                     if (!toFocus.requestFocus(false,
 161                                                    FocusEvent.Cause.ROLLBACK)) {
 162                         restoreFocusTo = toFocus;
 163                     }
 164                     return true;
 165                 }
 166             } else if (doRestoreFocus(toFocus, vetoedComponent, false)) {
 167                 return true;
 168             }
 169         }
 170         if (clearOnFailure) {
 171             clearGlobalFocusOwnerPriv();
 172             return true;
 173         } else {
 174             return false;
 175         }
 176     }
 177     private boolean restoreFocus(Component toFocus, boolean clearOnFailure) {
 178         return doRestoreFocus(toFocus, null, clearOnFailure);
 179     }
 180     private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
 181                                    boolean clearOnFailure)
 182     {
 183         if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.canBeFocusOwner() &&
 184             toFocus.requestFocus(false, FocusEvent.Cause.ROLLBACK))
 185         {
 186             return true;


 412                     // in the Window.
 413                     //
 414                     // * If we're in SendMessage, then this is a synthetic
 415                     //   WINDOW_GAINED_FOCUS message which was generated by a
 416                     //   the FOCUS_GAINED handler. Allow the Component to
 417                     //   which the FOCUS_GAINED message was targeted to
 418                     //   receive the focus.
 419                     // * Otherwise, look up the correct Component here.
 420                     //   We don't use Window.getMostRecentFocusOwner because
 421                     //   window is focused now and 'null' will be returned
 422 
 423 
 424                     // Calculating of most recent focus owner and focus
 425                     // request should be synchronized on KeyboardFocusManager.class
 426                     // to prevent from thread race when user will request
 427                     // focus between calculation and our request.
 428                     // But if focus transfer is synchronous, this synchronization
 429                     // may cause deadlock, thus we don't synchronize this block.
 430                     Component toFocus = KeyboardFocusManager.
 431                         getMostRecentFocusOwner(newFocusedWindow);
 432                     boolean isFocusRestore = restoreFocusTo != null &&
 433                                                       toFocus == restoreFocusTo;
 434                     if ((toFocus == null) &&
 435                         newFocusedWindow.isFocusableWindow())
 436                     {
 437                         toFocus = newFocusedWindow.getFocusTraversalPolicy().
 438                             getInitialComponent(newFocusedWindow);
 439                     }
 440                     Component tempLost = null;
 441                     synchronized(KeyboardFocusManager.class) {
 442                         tempLost = newFocusedWindow.setTemporaryLostComponent(null);
 443                     }
 444 
 445                     // The component which last has the focus when this window was focused
 446                     // should receive focus first
 447                     if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
 448                         focusLog.finer("tempLost {0}, toFocus {1}",
 449                                        tempLost, toFocus);
 450                     }
 451                     if (tempLost != null) {
 452                         tempLost.requestFocusInWindow(isFocusRestore ?
 453                                                 FocusEvent.Cause.ROLLBACK :
 454                                                 FocusEvent.Cause.ACTIVATION);
 455                     }
 456 
 457                     if (toFocus != null && toFocus != tempLost) {
 458                         // If there is a component which requested focus when this window
 459                         // was inactive it expects to receive focus after activation.
 460                         toFocus.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);
 461                     }
 462                 }
 463                 restoreFocusTo = null;
 464 
 465                 Window realOppositeWindow = this.realOppositeWindowWR.get();
 466                 if (realOppositeWindow != we.getOppositeWindow()) {
 467                     we = new WindowEvent(newFocusedWindow,
 468                                          WindowEvent.WINDOW_GAINED_FOCUS,
 469                                          realOppositeWindow);
 470                 }
 471                 return typeAheadAssertions(newFocusedWindow, we);
 472             }
 473 
 474             case WindowEvent.WINDOW_ACTIVATED: {
 475                 WindowEvent we = (WindowEvent)e;
 476                 Window oldActiveWindow = getGlobalActiveWindow();
 477                 Window newActiveWindow = we.getWindow();
 478                 if (oldActiveWindow == newActiveWindow) {
 479                     break;
 480                 }
 481 
 482                 // If there exists a current active window, then notify it that
 483                 // it has lost activation.


 493                     }
 494                     if (getGlobalActiveWindow() != null) {
 495                         // Activation change was rejected. Unlikely, but
 496                         // possible.
 497                         break;
 498                     }
 499                 }
 500 
 501                 setGlobalActiveWindow(newActiveWindow);
 502 
 503                 if (newActiveWindow != getGlobalActiveWindow()) {
 504                     // Activation change was rejected. Unlikely, but
 505                     // possible.
 506                     break;
 507                 }
 508 
 509                 return typeAheadAssertions(newActiveWindow, we);
 510             }
 511 
 512             case FocusEvent.FOCUS_GAINED: {
 513                 restoreFocusTo = null;
 514                 FocusEvent fe = (FocusEvent)e;
 515                 Component oldFocusOwner = getGlobalFocusOwner();
 516                 Component newFocusOwner = fe.getComponent();
 517                 if (oldFocusOwner == newFocusOwner) {
 518                     if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
 519                         focusLog.fine("Skipping {0} because focus owner is the same", e);
 520                     }
 521                     // We can't just drop the event - there could be
 522                     // type-ahead markers associated with it.
 523                     dequeueKeyEvents(-1, newFocusOwner);
 524                     break;
 525                 }
 526 
 527                 // If there exists a current focus owner, then notify it that
 528                 // it has lost focus.
 529                 if (oldFocusOwner != null) {
 530                     boolean isEventDispatched =
 531                         sendMessage(oldFocusOwner,
 532                                     new FocusEvent(oldFocusOwner,
 533                                                    FocusEvent.FOCUS_LOST,


< prev index next >