51 import java.beans.PropertyChangeSupport;
52 import java.beans.Transient;
53 import java.awt.im.InputContext;
54 import java.awt.im.InputMethodRequests;
55 import java.awt.dnd.DropTarget;
56 import java.lang.reflect.InvocationTargetException;
57 import java.lang.reflect.Method;
58 import java.security.AccessController;
59 import java.security.PrivilegedAction;
60 import java.security.AccessControlContext;
61 import javax.accessibility.*;
62 import java.applet.Applet;
63
64 import sun.awt.ComponentFactory;
65 import sun.security.action.GetPropertyAction;
66 import sun.awt.AppContext;
67 import sun.awt.AWTAccessor;
68 import sun.awt.ConstrainableGraphics;
69 import sun.awt.SubRegionShowable;
70 import sun.awt.SunToolkit;
71 import sun.awt.CausedFocusEvent;
72 import sun.awt.EmbeddedFrame;
73 import sun.awt.dnd.SunDropTargetEvent;
74 import sun.awt.im.CompositionArea;
75 import sun.font.FontManager;
76 import sun.font.FontManagerFactory;
77 import sun.font.SunFontManager;
78 import sun.java2d.SunGraphics2D;
79 import sun.java2d.pipe.Region;
80 import sun.awt.image.VSyncedBSManager;
81 import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
82 import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*;
83 import sun.awt.RequestFocusController;
84 import sun.java2d.SunGraphicsEnvironment;
85 import sun.util.logging.PlatformLogger;
86
87 /**
88 * A <em>component</em> is an object having a graphical representation
89 * that can be displayed on the screen and that can interact with the
90 * user. Examples of components are the buttons, checkboxes, and scrollbars
91 * of a typical graphical user interface. <p>
861 if (!comp.isNonOpaqueForMixing()) {
862 needShowing = true;
863 }
864
865 if (comp.isMixingNeeded()) {
866 if (needHiding) {
867 comp.mixOnHiding(comp.isLightweight());
868 }
869 if (needShowing) {
870 comp.mixOnShowing();
871 }
872 }
873 }
874 }
875
876 public void setGraphicsConfiguration(Component comp,
877 GraphicsConfiguration gc)
878 {
879 comp.setGraphicsConfiguration(gc);
880 }
881 public boolean requestFocus(Component comp, CausedFocusEvent.Cause cause) {
882 return comp.requestFocus(cause);
883 }
884 public boolean canBeFocusOwner(Component comp) {
885 return comp.canBeFocusOwner();
886 }
887
888 public boolean isVisible(Component comp) {
889 return comp.isVisible_NoClientCode();
890 }
891 public void setRequestFocusController
892 (RequestFocusController requestController)
893 {
894 Component.setRequestFocusController(requestController);
895 }
896 public AppContext getAppContext(Component comp) {
897 return comp.appContext;
898 }
899 public void setAppContext(Component comp, AppContext appContext) {
900 comp.appContext = appContext;
901 }
7521 * Because the focus behavior of this method is platform-dependent,
7522 * developers are strongly encouraged to use
7523 * {@code requestFocusInWindow} when possible.
7524 *
7525 * <p>Note: Not all focus transfers result from invoking this method. As
7526 * such, a component may receive focus without this or any of the other
7527 * {@code requestFocus} methods of {@code Component} being invoked.
7528 *
7529 * @see #requestFocusInWindow
7530 * @see java.awt.event.FocusEvent
7531 * @see #addFocusListener
7532 * @see #isFocusable
7533 * @see #isDisplayable
7534 * @see KeyboardFocusManager#clearGlobalFocusOwner
7535 * @since 1.0
7536 */
7537 public void requestFocus() {
7538 requestFocusHelper(false, true);
7539 }
7540
7541 boolean requestFocus(CausedFocusEvent.Cause cause) {
7542 return requestFocusHelper(false, true, cause);
7543 }
7544
7545 /**
7546 * Requests that this {@code Component} get the input focus,
7547 * and that this {@code Component}'s top-level ancestor
7548 * become the focused {@code Window}. This component must be
7549 * displayable, focusable, visible and all of its ancestors (with
7550 * the exception of the top-level Window) must be visible for the
7551 * request to be granted. Every effort will be made to honor the
7552 * request; however, in some cases it may be impossible to do
7553 * so. Developers must never assume that this component is the
7554 * focus owner until this component receives a FOCUS_GAINED
7555 * event. If this request is denied because this component's
7556 * top-level window cannot become the focused window, the request
7557 * will be remembered and will be granted when the window is later
7558 * focused by the user.
7559 * <p>
7560 * This method returns a boolean value. If {@code false} is returned,
7561 * the request is <b>guaranteed to fail</b>. If {@code true} is
7588 * such, a component may receive focus without this or any of the other
7589 * {@code requestFocus} methods of {@code Component} being invoked.
7590 *
7591 * @param temporary true if the focus change is temporary,
7592 * such as when the window loses the focus; for
7593 * more information on temporary focus changes see the
7594 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7595 * @return {@code false} if the focus change request is guaranteed to
7596 * fail; {@code true} if it is likely to succeed
7597 * @see java.awt.event.FocusEvent
7598 * @see #addFocusListener
7599 * @see #isFocusable
7600 * @see #isDisplayable
7601 * @see KeyboardFocusManager#clearGlobalFocusOwner
7602 * @since 1.4
7603 */
7604 protected boolean requestFocus(boolean temporary) {
7605 return requestFocusHelper(temporary, true);
7606 }
7607
7608 boolean requestFocus(boolean temporary, CausedFocusEvent.Cause cause) {
7609 return requestFocusHelper(temporary, true, cause);
7610 }
7611 /**
7612 * Requests that this Component get the input focus, if this
7613 * Component's top-level ancestor is already the focused
7614 * Window. This component must be displayable, focusable, visible
7615 * and all of its ancestors (with the exception of the top-level
7616 * Window) must be visible for the request to be granted. Every
7617 * effort will be made to honor the request; however, in some
7618 * cases it may be impossible to do so. Developers must never
7619 * assume that this Component is the focus owner until this
7620 * Component receives a FOCUS_GAINED event.
7621 * <p>
7622 * This method returns a boolean value. If {@code false} is returned,
7623 * the request is <b>guaranteed to fail</b>. If {@code true} is
7624 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7625 * extraordinary event, such as disposal of the Component's peer, occurs
7626 * before the request can be granted by the native windowing system. Again,
7627 * while a return value of {@code true} indicates that the request is
7628 * likely to succeed, developers must never assume that this Component is
7639 * different platforms.
7640 *
7641 * <p>Note: Not all focus transfers result from invoking this method. As
7642 * such, a component may receive focus without this or any of the other
7643 * {@code requestFocus} methods of {@code Component} being invoked.
7644 *
7645 * @return {@code false} if the focus change request is guaranteed to
7646 * fail; {@code true} if it is likely to succeed
7647 * @see #requestFocus
7648 * @see java.awt.event.FocusEvent
7649 * @see #addFocusListener
7650 * @see #isFocusable
7651 * @see #isDisplayable
7652 * @see KeyboardFocusManager#clearGlobalFocusOwner
7653 * @since 1.4
7654 */
7655 public boolean requestFocusInWindow() {
7656 return requestFocusHelper(false, false);
7657 }
7658
7659 boolean requestFocusInWindow(CausedFocusEvent.Cause cause) {
7660 return requestFocusHelper(false, false, cause);
7661 }
7662
7663 /**
7664 * Requests that this {@code Component} get the input focus,
7665 * if this {@code Component}'s top-level ancestor is already
7666 * the focused {@code Window}. This component must be
7667 * displayable, focusable, visible and all of its ancestors (with
7668 * the exception of the top-level Window) must be visible for the
7669 * request to be granted. Every effort will be made to honor the
7670 * request; however, in some cases it may be impossible to do
7671 * so. Developers must never assume that this component is the
7672 * focus owner until this component receives a FOCUS_GAINED event.
7673 * <p>
7674 * This method returns a boolean value. If {@code false} is returned,
7675 * the request is <b>guaranteed to fail</b>. If {@code true} is
7676 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7677 * extraordinary event, such as disposal of the component's peer, occurs
7678 * before the request can be granted by the native windowing system. Again,
7679 * while a return value of {@code true} indicates that the request is
7704 * {@code requestFocus} methods of {@code Component} being invoked.
7705 *
7706 * @param temporary true if the focus change is temporary,
7707 * such as when the window loses the focus; for
7708 * more information on temporary focus changes see the
7709 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7710 * @return {@code false} if the focus change request is guaranteed to
7711 * fail; {@code true} if it is likely to succeed
7712 * @see #requestFocus
7713 * @see java.awt.event.FocusEvent
7714 * @see #addFocusListener
7715 * @see #isFocusable
7716 * @see #isDisplayable
7717 * @see KeyboardFocusManager#clearGlobalFocusOwner
7718 * @since 1.4
7719 */
7720 protected boolean requestFocusInWindow(boolean temporary) {
7721 return requestFocusHelper(temporary, false);
7722 }
7723
7724 boolean requestFocusInWindow(boolean temporary, CausedFocusEvent.Cause cause) {
7725 return requestFocusHelper(temporary, false, cause);
7726 }
7727
7728 final boolean requestFocusHelper(boolean temporary,
7729 boolean focusedWindowChangeAllowed) {
7730 return requestFocusHelper(temporary, focusedWindowChangeAllowed, CausedFocusEvent.Cause.UNKNOWN);
7731 }
7732
7733 final boolean requestFocusHelper(boolean temporary,
7734 boolean focusedWindowChangeAllowed,
7735 CausedFocusEvent.Cause cause)
7736 {
7737 // 1) Check if the event being dispatched is a system-generated mouse event.
7738 AWTEvent currentEvent = EventQueue.getCurrentEvent();
7739 if (currentEvent instanceof MouseEvent &&
7740 SunToolkit.isSystemGenerated(currentEvent))
7741 {
7742 // 2) Sanity check: if the mouse event component source belongs to the same containing window.
7743 Component source = ((MouseEvent)currentEvent).getComponent();
7744 if (source == null || source.getContainingWindow() == getContainingWindow()) {
7745 focusLog.finest("requesting focus by mouse event \"in window\"");
7746
7747 // If both the conditions are fulfilled the focus request should be strictly
7748 // bounded by the toplevel window. It's assumed that the mouse event activates
7749 // the window (if it wasn't active) and this makes it possible for a focus
7750 // request with a strong in-window requirement to change focus in the bounds
7751 // of the toplevel. If, by any means, due to asynchronous nature of the event
7752 // dispatching mechanism, the window happens to be natively inactive by the time
7753 // this focus request is eventually handled, it should not re-activate the
7754 // toplevel. Otherwise the result may not meet user expectations. See 6981400.
7755 focusedWindowChangeAllowed = false;
7803 }
7804
7805 boolean success = peer.requestFocus
7806 (this, temporary, focusedWindowChangeAllowed, time, cause);
7807 if (!success) {
7808 KeyboardFocusManager.getCurrentKeyboardFocusManager
7809 (appContext).dequeueKeyEvents(time, this);
7810 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7811 focusLog.finest("Peer request failed");
7812 }
7813 } else {
7814 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7815 focusLog.finest("Pass for " + this);
7816 }
7817 }
7818 return success;
7819 }
7820
7821 private boolean isRequestFocusAccepted(boolean temporary,
7822 boolean focusedWindowChangeAllowed,
7823 CausedFocusEvent.Cause cause)
7824 {
7825 if (!isFocusable() || !isVisible()) {
7826 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7827 focusLog.finest("Not focusable or not visible");
7828 }
7829 return false;
7830 }
7831
7832 ComponentPeer peer = this.peer;
7833 if (peer == null) {
7834 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7835 focusLog.finest("peer is null");
7836 }
7837 return false;
7838 }
7839
7840 Window window = getContainingWindow();
7841 if (window == null || !window.isFocusableWindow()) {
7842 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7843 focusLog.finest("Component doesn't have toplevel");
7850 Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window);
7851 if (focusOwner == null) {
7852 // sometimes most recent focus owner may be null, but focus owner is not
7853 // e.g. we reset most recent focus owner if user removes focus owner
7854 focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
7855 if (focusOwner != null && focusOwner.getContainingWindow() != window) {
7856 focusOwner = null;
7857 }
7858 }
7859
7860 if (focusOwner == this || focusOwner == null) {
7861 // Controller is supposed to verify focus transfers and for this it
7862 // should know both from and to components. And it shouldn't verify
7863 // transfers from when these components are equal.
7864 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7865 focusLog.finest("focus owner is null or this");
7866 }
7867 return true;
7868 }
7869
7870 if (CausedFocusEvent.Cause.ACTIVATION == cause) {
7871 // we shouldn't call RequestFocusController in case we are
7872 // in activation. We do request focus on component which
7873 // has got temporary focus lost and then on component which is
7874 // most recent focus owner. But most recent focus owner can be
7875 // changed by requestFocusXXX() call only, so this transfer has
7876 // been already approved.
7877 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7878 focusLog.finest("cause is activation");
7879 }
7880 return true;
7881 }
7882
7883 boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
7884 this,
7885 temporary,
7886 focusedWindowChangeAllowed,
7887 cause);
7888 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7889 focusLog.finest("RequestFocusController returns {0}", ret);
7890 }
7891
7892 return ret;
7893 }
7894
7895 private static RequestFocusController requestFocusController = new DummyRequestFocusController();
7896
7897 // Swing access this method through reflection to implement InputVerifier's functionality.
7898 // Perhaps, we should make this method public (later ;)
7899 private static class DummyRequestFocusController implements RequestFocusController {
7900 public boolean acceptRequestFocus(Component from, Component to,
7901 boolean temporary, boolean focusedWindowChangeAllowed,
7902 CausedFocusEvent.Cause cause)
7903 {
7904 return true;
7905 }
7906 };
7907
7908 static synchronized void setRequestFocusController(RequestFocusController requestController)
7909 {
7910 if (requestController == null) {
7911 requestFocusController = new DummyRequestFocusController();
7912 } else {
7913 requestFocusController = requestController;
7914 }
7915 }
7916
7917 /**
7918 * Returns the Container which is the focus cycle root of this Component's
7919 * focus traversal cycle. Each focus traversal cycle has only a single
7920 * focus cycle root and each Component which is not a Container belongs to
7921 * only a single focus traversal cycle. Containers which are focus cycle
7922 * roots belong to two cycles: one rooted at the Container itself, and one
7966 public void transferFocus() {
7967 nextFocus();
7968 }
7969
7970 /**
7971 * @deprecated As of JDK version 1.1,
7972 * replaced by transferFocus().
7973 */
7974 @Deprecated
7975 public void nextFocus() {
7976 transferFocus(false);
7977 }
7978
7979 boolean transferFocus(boolean clearOnFailure) {
7980 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
7981 focusLog.finer("clearOnFailure = " + clearOnFailure);
7982 }
7983 Component toFocus = getNextFocusCandidate();
7984 boolean res = false;
7985 if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
7986 res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
7987 }
7988 if (clearOnFailure && !res) {
7989 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
7990 focusLog.finer("clear global focus owner");
7991 }
7992 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
7993 }
7994 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
7995 focusLog.finer("returning result: " + res);
7996 }
7997 return res;
7998 }
7999
8000 final Component getNextFocusCandidate() {
8001 Container rootAncestor = getTraversalRoot();
8002 Component comp = this;
8003 while (rootAncestor != null &&
8004 !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
8005 {
8006 comp = rootAncestor;
8046 transferFocusBackward(false);
8047 }
8048
8049 boolean transferFocusBackward(boolean clearOnFailure) {
8050 Container rootAncestor = getTraversalRoot();
8051 Component comp = this;
8052 while (rootAncestor != null &&
8053 !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
8054 {
8055 comp = rootAncestor;
8056 rootAncestor = comp.getFocusCycleRootAncestor();
8057 }
8058 boolean res = false;
8059 if (rootAncestor != null) {
8060 FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
8061 Component toFocus = policy.getComponentBefore(rootAncestor, comp);
8062 if (toFocus == null) {
8063 toFocus = policy.getDefaultComponent(rootAncestor);
8064 }
8065 if (toFocus != null) {
8066 res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
8067 }
8068 }
8069 if (clearOnFailure && !res) {
8070 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8071 focusLog.finer("clear global focus owner");
8072 }
8073 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
8074 }
8075 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8076 focusLog.finer("returning result: " + res);
8077 }
8078 return res;
8079 }
8080
8081 /**
8082 * Transfers the focus up one focus traversal cycle. Typically, the focus
8083 * owner is set to this Component's focus cycle root, and the current focus
8084 * cycle root is set to the new focus owner's focus cycle root. If,
8085 * however, this Component's focus cycle root is a Window, then the focus
8086 * owner is set to the focus cycle root's default Component to focus, and
8091 * @see Container#setFocusCycleRoot(boolean)
8092 * @since 1.4
8093 */
8094 public void transferFocusUpCycle() {
8095 Container rootAncestor;
8096 for (rootAncestor = getFocusCycleRootAncestor();
8097 rootAncestor != null && !(rootAncestor.isShowing() &&
8098 rootAncestor.isFocusable() &&
8099 rootAncestor.isEnabled());
8100 rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
8101 }
8102
8103 if (rootAncestor != null) {
8104 Container rootAncestorRootAncestor =
8105 rootAncestor.getFocusCycleRootAncestor();
8106 Container fcr = (rootAncestorRootAncestor != null) ?
8107 rootAncestorRootAncestor : rootAncestor;
8108
8109 KeyboardFocusManager.getCurrentKeyboardFocusManager().
8110 setGlobalCurrentFocusCycleRootPriv(fcr);
8111 rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
8112 } else {
8113 Window window = getContainingWindow();
8114
8115 if (window != null) {
8116 Component toFocus = window.getFocusTraversalPolicy().
8117 getDefaultComponent(window);
8118 if (toFocus != null) {
8119 KeyboardFocusManager.getCurrentKeyboardFocusManager().
8120 setGlobalCurrentFocusCycleRootPriv(window);
8121 toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
8122 }
8123 }
8124 }
8125 }
8126
8127 /**
8128 * Returns {@code true} if this {@code Component} is the
8129 * focus owner. This method is obsolete, and has been replaced by
8130 * {@code isFocusOwner()}.
8131 *
8132 * @return {@code true} if this {@code Component} is the
8133 * focus owner; {@code false} otherwise
8134 * @since 1.2
8135 */
8136 public boolean hasFocus() {
8137 return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
8138 getFocusOwner() == this);
8139 }
8140
8141 /**
|
51 import java.beans.PropertyChangeSupport;
52 import java.beans.Transient;
53 import java.awt.im.InputContext;
54 import java.awt.im.InputMethodRequests;
55 import java.awt.dnd.DropTarget;
56 import java.lang.reflect.InvocationTargetException;
57 import java.lang.reflect.Method;
58 import java.security.AccessController;
59 import java.security.PrivilegedAction;
60 import java.security.AccessControlContext;
61 import javax.accessibility.*;
62 import java.applet.Applet;
63
64 import sun.awt.ComponentFactory;
65 import sun.security.action.GetPropertyAction;
66 import sun.awt.AppContext;
67 import sun.awt.AWTAccessor;
68 import sun.awt.ConstrainableGraphics;
69 import sun.awt.SubRegionShowable;
70 import sun.awt.SunToolkit;
71 import sun.awt.EmbeddedFrame;
72 import sun.awt.dnd.SunDropTargetEvent;
73 import sun.awt.im.CompositionArea;
74 import sun.font.FontManager;
75 import sun.font.FontManagerFactory;
76 import sun.font.SunFontManager;
77 import sun.java2d.SunGraphics2D;
78 import sun.java2d.pipe.Region;
79 import sun.awt.image.VSyncedBSManager;
80 import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
81 import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*;
82 import sun.awt.RequestFocusController;
83 import sun.java2d.SunGraphicsEnvironment;
84 import sun.util.logging.PlatformLogger;
85
86 /**
87 * A <em>component</em> is an object having a graphical representation
88 * that can be displayed on the screen and that can interact with the
89 * user. Examples of components are the buttons, checkboxes, and scrollbars
90 * of a typical graphical user interface. <p>
860 if (!comp.isNonOpaqueForMixing()) {
861 needShowing = true;
862 }
863
864 if (comp.isMixingNeeded()) {
865 if (needHiding) {
866 comp.mixOnHiding(comp.isLightweight());
867 }
868 if (needShowing) {
869 comp.mixOnShowing();
870 }
871 }
872 }
873 }
874
875 public void setGraphicsConfiguration(Component comp,
876 GraphicsConfiguration gc)
877 {
878 comp.setGraphicsConfiguration(gc);
879 }
880 public boolean requestFocus(Component comp, FocusEvent.Cause cause) {
881 return comp.requestFocus(cause);
882 }
883 public boolean canBeFocusOwner(Component comp) {
884 return comp.canBeFocusOwner();
885 }
886
887 public boolean isVisible(Component comp) {
888 return comp.isVisible_NoClientCode();
889 }
890 public void setRequestFocusController
891 (RequestFocusController requestController)
892 {
893 Component.setRequestFocusController(requestController);
894 }
895 public AppContext getAppContext(Component comp) {
896 return comp.appContext;
897 }
898 public void setAppContext(Component comp, AppContext appContext) {
899 comp.appContext = appContext;
900 }
7520 * Because the focus behavior of this method is platform-dependent,
7521 * developers are strongly encouraged to use
7522 * {@code requestFocusInWindow} when possible.
7523 *
7524 * <p>Note: Not all focus transfers result from invoking this method. As
7525 * such, a component may receive focus without this or any of the other
7526 * {@code requestFocus} methods of {@code Component} being invoked.
7527 *
7528 * @see #requestFocusInWindow
7529 * @see java.awt.event.FocusEvent
7530 * @see #addFocusListener
7531 * @see #isFocusable
7532 * @see #isDisplayable
7533 * @see KeyboardFocusManager#clearGlobalFocusOwner
7534 * @since 1.0
7535 */
7536 public void requestFocus() {
7537 requestFocusHelper(false, true);
7538 }
7539
7540 boolean requestFocus(FocusEvent.Cause cause) {
7541 return requestFocusHelper(false, true, cause);
7542 }
7543
7544 /**
7545 * Requests that this {@code Component} get the input focus,
7546 * and that this {@code Component}'s top-level ancestor
7547 * become the focused {@code Window}. This component must be
7548 * displayable, focusable, visible and all of its ancestors (with
7549 * the exception of the top-level Window) must be visible for the
7550 * request to be granted. Every effort will be made to honor the
7551 * request; however, in some cases it may be impossible to do
7552 * so. Developers must never assume that this component is the
7553 * focus owner until this component receives a FOCUS_GAINED
7554 * event. If this request is denied because this component's
7555 * top-level window cannot become the focused window, the request
7556 * will be remembered and will be granted when the window is later
7557 * focused by the user.
7558 * <p>
7559 * This method returns a boolean value. If {@code false} is returned,
7560 * the request is <b>guaranteed to fail</b>. If {@code true} is
7587 * such, a component may receive focus without this or any of the other
7588 * {@code requestFocus} methods of {@code Component} being invoked.
7589 *
7590 * @param temporary true if the focus change is temporary,
7591 * such as when the window loses the focus; for
7592 * more information on temporary focus changes see the
7593 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7594 * @return {@code false} if the focus change request is guaranteed to
7595 * fail; {@code true} if it is likely to succeed
7596 * @see java.awt.event.FocusEvent
7597 * @see #addFocusListener
7598 * @see #isFocusable
7599 * @see #isDisplayable
7600 * @see KeyboardFocusManager#clearGlobalFocusOwner
7601 * @since 1.4
7602 */
7603 protected boolean requestFocus(boolean temporary) {
7604 return requestFocusHelper(temporary, true);
7605 }
7606
7607 boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
7608 return requestFocusHelper(temporary, true, cause);
7609 }
7610 /**
7611 * Requests that this Component get the input focus, if this
7612 * Component's top-level ancestor is already the focused
7613 * Window. This component must be displayable, focusable, visible
7614 * and all of its ancestors (with the exception of the top-level
7615 * Window) must be visible for the request to be granted. Every
7616 * effort will be made to honor the request; however, in some
7617 * cases it may be impossible to do so. Developers must never
7618 * assume that this Component is the focus owner until this
7619 * Component receives a FOCUS_GAINED event.
7620 * <p>
7621 * This method returns a boolean value. If {@code false} is returned,
7622 * the request is <b>guaranteed to fail</b>. If {@code true} is
7623 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7624 * extraordinary event, such as disposal of the Component's peer, occurs
7625 * before the request can be granted by the native windowing system. Again,
7626 * while a return value of {@code true} indicates that the request is
7627 * likely to succeed, developers must never assume that this Component is
7638 * different platforms.
7639 *
7640 * <p>Note: Not all focus transfers result from invoking this method. As
7641 * such, a component may receive focus without this or any of the other
7642 * {@code requestFocus} methods of {@code Component} being invoked.
7643 *
7644 * @return {@code false} if the focus change request is guaranteed to
7645 * fail; {@code true} if it is likely to succeed
7646 * @see #requestFocus
7647 * @see java.awt.event.FocusEvent
7648 * @see #addFocusListener
7649 * @see #isFocusable
7650 * @see #isDisplayable
7651 * @see KeyboardFocusManager#clearGlobalFocusOwner
7652 * @since 1.4
7653 */
7654 public boolean requestFocusInWindow() {
7655 return requestFocusHelper(false, false);
7656 }
7657
7658 boolean requestFocusInWindow(FocusEvent.Cause cause) {
7659 return requestFocusHelper(false, false, cause);
7660 }
7661
7662 /**
7663 * Requests that this {@code Component} get the input focus,
7664 * if this {@code Component}'s top-level ancestor is already
7665 * the focused {@code Window}. This component must be
7666 * displayable, focusable, visible and all of its ancestors (with
7667 * the exception of the top-level Window) must be visible for the
7668 * request to be granted. Every effort will be made to honor the
7669 * request; however, in some cases it may be impossible to do
7670 * so. Developers must never assume that this component is the
7671 * focus owner until this component receives a FOCUS_GAINED event.
7672 * <p>
7673 * This method returns a boolean value. If {@code false} is returned,
7674 * the request is <b>guaranteed to fail</b>. If {@code true} is
7675 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7676 * extraordinary event, such as disposal of the component's peer, occurs
7677 * before the request can be granted by the native windowing system. Again,
7678 * while a return value of {@code true} indicates that the request is
7703 * {@code requestFocus} methods of {@code Component} being invoked.
7704 *
7705 * @param temporary true if the focus change is temporary,
7706 * such as when the window loses the focus; for
7707 * more information on temporary focus changes see the
7708 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7709 * @return {@code false} if the focus change request is guaranteed to
7710 * fail; {@code true} if it is likely to succeed
7711 * @see #requestFocus
7712 * @see java.awt.event.FocusEvent
7713 * @see #addFocusListener
7714 * @see #isFocusable
7715 * @see #isDisplayable
7716 * @see KeyboardFocusManager#clearGlobalFocusOwner
7717 * @since 1.4
7718 */
7719 protected boolean requestFocusInWindow(boolean temporary) {
7720 return requestFocusHelper(temporary, false);
7721 }
7722
7723 boolean requestFocusInWindow(boolean temporary, FocusEvent.Cause cause) {
7724 return requestFocusHelper(temporary, false, cause);
7725 }
7726
7727 final boolean requestFocusHelper(boolean temporary,
7728 boolean focusedWindowChangeAllowed) {
7729 return requestFocusHelper(temporary, focusedWindowChangeAllowed, FocusEvent.Cause.UNKNOWN);
7730 }
7731
7732 final boolean requestFocusHelper(boolean temporary,
7733 boolean focusedWindowChangeAllowed,
7734 FocusEvent.Cause cause)
7735 {
7736 // 1) Check if the event being dispatched is a system-generated mouse event.
7737 AWTEvent currentEvent = EventQueue.getCurrentEvent();
7738 if (currentEvent instanceof MouseEvent &&
7739 SunToolkit.isSystemGenerated(currentEvent))
7740 {
7741 // 2) Sanity check: if the mouse event component source belongs to the same containing window.
7742 Component source = ((MouseEvent)currentEvent).getComponent();
7743 if (source == null || source.getContainingWindow() == getContainingWindow()) {
7744 focusLog.finest("requesting focus by mouse event \"in window\"");
7745
7746 // If both the conditions are fulfilled the focus request should be strictly
7747 // bounded by the toplevel window. It's assumed that the mouse event activates
7748 // the window (if it wasn't active) and this makes it possible for a focus
7749 // request with a strong in-window requirement to change focus in the bounds
7750 // of the toplevel. If, by any means, due to asynchronous nature of the event
7751 // dispatching mechanism, the window happens to be natively inactive by the time
7752 // this focus request is eventually handled, it should not re-activate the
7753 // toplevel. Otherwise the result may not meet user expectations. See 6981400.
7754 focusedWindowChangeAllowed = false;
7802 }
7803
7804 boolean success = peer.requestFocus
7805 (this, temporary, focusedWindowChangeAllowed, time, cause);
7806 if (!success) {
7807 KeyboardFocusManager.getCurrentKeyboardFocusManager
7808 (appContext).dequeueKeyEvents(time, this);
7809 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7810 focusLog.finest("Peer request failed");
7811 }
7812 } else {
7813 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7814 focusLog.finest("Pass for " + this);
7815 }
7816 }
7817 return success;
7818 }
7819
7820 private boolean isRequestFocusAccepted(boolean temporary,
7821 boolean focusedWindowChangeAllowed,
7822 FocusEvent.Cause cause)
7823 {
7824 if (!isFocusable() || !isVisible()) {
7825 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7826 focusLog.finest("Not focusable or not visible");
7827 }
7828 return false;
7829 }
7830
7831 ComponentPeer peer = this.peer;
7832 if (peer == null) {
7833 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7834 focusLog.finest("peer is null");
7835 }
7836 return false;
7837 }
7838
7839 Window window = getContainingWindow();
7840 if (window == null || !window.isFocusableWindow()) {
7841 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7842 focusLog.finest("Component doesn't have toplevel");
7849 Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window);
7850 if (focusOwner == null) {
7851 // sometimes most recent focus owner may be null, but focus owner is not
7852 // e.g. we reset most recent focus owner if user removes focus owner
7853 focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
7854 if (focusOwner != null && focusOwner.getContainingWindow() != window) {
7855 focusOwner = null;
7856 }
7857 }
7858
7859 if (focusOwner == this || focusOwner == null) {
7860 // Controller is supposed to verify focus transfers and for this it
7861 // should know both from and to components. And it shouldn't verify
7862 // transfers from when these components are equal.
7863 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7864 focusLog.finest("focus owner is null or this");
7865 }
7866 return true;
7867 }
7868
7869 if (FocusEvent.Cause.ACTIVATION == cause) {
7870 // we shouldn't call RequestFocusController in case we are
7871 // in activation. We do request focus on component which
7872 // has got temporary focus lost and then on component which is
7873 // most recent focus owner. But most recent focus owner can be
7874 // changed by requestFocusXXX() call only, so this transfer has
7875 // been already approved.
7876 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7877 focusLog.finest("cause is activation");
7878 }
7879 return true;
7880 }
7881
7882 boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
7883 this,
7884 temporary,
7885 focusedWindowChangeAllowed,
7886 cause);
7887 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7888 focusLog.finest("RequestFocusController returns {0}", ret);
7889 }
7890
7891 return ret;
7892 }
7893
7894 private static RequestFocusController requestFocusController = new DummyRequestFocusController();
7895
7896 // Swing access this method through reflection to implement InputVerifier's functionality.
7897 // Perhaps, we should make this method public (later ;)
7898 private static class DummyRequestFocusController implements RequestFocusController {
7899 public boolean acceptRequestFocus(Component from, Component to,
7900 boolean temporary, boolean focusedWindowChangeAllowed,
7901 FocusEvent.Cause cause)
7902 {
7903 return true;
7904 }
7905 };
7906
7907 static synchronized void setRequestFocusController(RequestFocusController requestController)
7908 {
7909 if (requestController == null) {
7910 requestFocusController = new DummyRequestFocusController();
7911 } else {
7912 requestFocusController = requestController;
7913 }
7914 }
7915
7916 /**
7917 * Returns the Container which is the focus cycle root of this Component's
7918 * focus traversal cycle. Each focus traversal cycle has only a single
7919 * focus cycle root and each Component which is not a Container belongs to
7920 * only a single focus traversal cycle. Containers which are focus cycle
7921 * roots belong to two cycles: one rooted at the Container itself, and one
7965 public void transferFocus() {
7966 nextFocus();
7967 }
7968
7969 /**
7970 * @deprecated As of JDK version 1.1,
7971 * replaced by transferFocus().
7972 */
7973 @Deprecated
7974 public void nextFocus() {
7975 transferFocus(false);
7976 }
7977
7978 boolean transferFocus(boolean clearOnFailure) {
7979 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
7980 focusLog.finer("clearOnFailure = " + clearOnFailure);
7981 }
7982 Component toFocus = getNextFocusCandidate();
7983 boolean res = false;
7984 if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
7985 res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_FORWARD);
7986 }
7987 if (clearOnFailure && !res) {
7988 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
7989 focusLog.finer("clear global focus owner");
7990 }
7991 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
7992 }
7993 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
7994 focusLog.finer("returning result: " + res);
7995 }
7996 return res;
7997 }
7998
7999 final Component getNextFocusCandidate() {
8000 Container rootAncestor = getTraversalRoot();
8001 Component comp = this;
8002 while (rootAncestor != null &&
8003 !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
8004 {
8005 comp = rootAncestor;
8045 transferFocusBackward(false);
8046 }
8047
8048 boolean transferFocusBackward(boolean clearOnFailure) {
8049 Container rootAncestor = getTraversalRoot();
8050 Component comp = this;
8051 while (rootAncestor != null &&
8052 !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
8053 {
8054 comp = rootAncestor;
8055 rootAncestor = comp.getFocusCycleRootAncestor();
8056 }
8057 boolean res = false;
8058 if (rootAncestor != null) {
8059 FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
8060 Component toFocus = policy.getComponentBefore(rootAncestor, comp);
8061 if (toFocus == null) {
8062 toFocus = policy.getDefaultComponent(rootAncestor);
8063 }
8064 if (toFocus != null) {
8065 res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_BACKWARD);
8066 }
8067 }
8068 if (clearOnFailure && !res) {
8069 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8070 focusLog.finer("clear global focus owner");
8071 }
8072 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
8073 }
8074 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8075 focusLog.finer("returning result: " + res);
8076 }
8077 return res;
8078 }
8079
8080 /**
8081 * Transfers the focus up one focus traversal cycle. Typically, the focus
8082 * owner is set to this Component's focus cycle root, and the current focus
8083 * cycle root is set to the new focus owner's focus cycle root. If,
8084 * however, this Component's focus cycle root is a Window, then the focus
8085 * owner is set to the focus cycle root's default Component to focus, and
8090 * @see Container#setFocusCycleRoot(boolean)
8091 * @since 1.4
8092 */
8093 public void transferFocusUpCycle() {
8094 Container rootAncestor;
8095 for (rootAncestor = getFocusCycleRootAncestor();
8096 rootAncestor != null && !(rootAncestor.isShowing() &&
8097 rootAncestor.isFocusable() &&
8098 rootAncestor.isEnabled());
8099 rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
8100 }
8101
8102 if (rootAncestor != null) {
8103 Container rootAncestorRootAncestor =
8104 rootAncestor.getFocusCycleRootAncestor();
8105 Container fcr = (rootAncestorRootAncestor != null) ?
8106 rootAncestorRootAncestor : rootAncestor;
8107
8108 KeyboardFocusManager.getCurrentKeyboardFocusManager().
8109 setGlobalCurrentFocusCycleRootPriv(fcr);
8110 rootAncestor.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);
8111 } else {
8112 Window window = getContainingWindow();
8113
8114 if (window != null) {
8115 Component toFocus = window.getFocusTraversalPolicy().
8116 getDefaultComponent(window);
8117 if (toFocus != null) {
8118 KeyboardFocusManager.getCurrentKeyboardFocusManager().
8119 setGlobalCurrentFocusCycleRootPriv(window);
8120 toFocus.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);
8121 }
8122 }
8123 }
8124 }
8125
8126 /**
8127 * Returns {@code true} if this {@code Component} is the
8128 * focus owner. This method is obsolete, and has been replaced by
8129 * {@code isFocusOwner()}.
8130 *
8131 * @return {@code true} if this {@code Component} is the
8132 * focus owner; {@code false} otherwise
8133 * @since 1.2
8134 */
8135 public boolean hasFocus() {
8136 return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
8137 getFocusOwner() == this);
8138 }
8139
8140 /**
|