--- a/jdk/src/share/classes/java/awt/Component.java Tue Apr 08 12:46:39 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Component.java Tue Apr 08 13:32:30 2008 +0400
@@ -1327,12 +1327,15 @@
KeyboardFocusManager.clearMostRecentFocusOwner(this);
synchronized (getTreeLock()) {
enabled = false;
- if (isFocusOwner()) {
+ // A disabled lw container is allowed to contain a focus owner.
+ if ((isFocusOwner() || (containsFocus() && !isLightweight())) &&
+ KeyboardFocusManager.isAutoFocusTransferEnabled())
+ {
// Don't clear the global focus owner. If transferFocus
// fails, we want the focus to stay on the disabled
// Component so that keyboard traversal, et. al. still
// makes sense to the user.
- autoTransferFocus(false);
+ transferFocus(false);
}
ComponentPeer peer = this.peer;
if (peer != null) {
@@ -1493,8 +1496,8 @@
synchronized (getTreeLock()) {
visible = false;
mixOnHiding(isLightweight());
- if (containsFocus()) {
- autoTransferFocus(true);
+ if (containsFocus() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {
+ transferFocus(true);
}
ComponentPeer peer = this.peer;
if (peer != null) {
@@ -6578,12 +6581,8 @@
}
synchronized (getTreeLock()) {
- if (isFocusOwner()
- && KeyboardFocusManager.isAutoFocusTransferEnabled()
- && !nextFocusHelper())
- {
- KeyboardFocusManager.getCurrentKeyboardFocusManager().
- clearGlobalFocusOwner();
+ if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
+ transferFocus(true);
}
if (getContainer() != null && isAddNotifyComplete) {
@@ -6718,8 +6717,8 @@
firePropertyChange("focusable", oldFocusable, focusable);
if (oldFocusable && !focusable) {
- if (isFocusOwner()) {
- autoTransferFocus(true);
+ if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {
+ transferFocus(true);
}
KeyboardFocusManager.clearMostRecentFocusOwner(this);
}
@@ -7373,69 +7372,6 @@
}
}
- private void autoTransferFocus(boolean clearOnFailure) {
- Component toTest = KeyboardFocusManager.
- getCurrentKeyboardFocusManager().getFocusOwner();
- if (toTest != this) {
- if (toTest != null) {
- toTest.autoTransferFocus(clearOnFailure);
- }
- return;
- }
-
- // Check if there are pending focus requests. We shouldn't do
- // auto-transfer if user has already took care of this
- // component becoming ineligible to hold focus.
- if (!KeyboardFocusManager.isAutoFocusTransferEnabled()) {
- return;
- }
-
- // the following code will execute only if this Component is the focus
- // owner
-
- if (!(isDisplayable() && isVisible() && isEnabled() && isFocusable())) {
- doAutoTransfer(clearOnFailure);
- return;
- }
-
- toTest = getParent();
-
- while (toTest != null && !(toTest instanceof Window)) {
- if (!(toTest.isDisplayable() && toTest.isVisible() &&
- (toTest.isEnabled() || toTest.isLightweight()))) {
- doAutoTransfer(clearOnFailure);
- return;
- }
- toTest = toTest.getParent();
- }
- }
- private void doAutoTransfer(boolean clearOnFailure) {
- if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "this = " + this + ", clearOnFailure = " + clearOnFailure);
- }
- if (clearOnFailure) {
- if (!nextFocusHelper()) {
- if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "clear global focus owner");
- }
- KeyboardFocusManager.getCurrentKeyboardFocusManager().
- clearGlobalFocusOwner();
- }
- } else {
- transferFocus();
- }
- }
-
- /**
- * Transfers the focus to the next component, as though this Component were
- * the focus owner.
- * @see #requestFocus()
- * @since JDK1.1
- */
- public void transferFocus() {
- nextFocus();
- }
-
/**
* Returns the Container which is the focus cycle root of this Component's
* focus traversal cycle. Each focus traversal cycle has only a single
@@ -7475,31 +7411,51 @@
return (rootAncestor == container);
}
+ Container getTraversalRoot() {
+ return getFocusCycleRootAncestor();
+ }
+
+ /**
+ * Transfers the focus to the next component, as though this Component were
+ * the focus owner.
+ * @see #requestFocus()
+ * @since JDK1.1
+ */
+ public void transferFocus() {
+ nextFocus();
+ }
+
/**
* @deprecated As of JDK version 1.1,
* replaced by transferFocus().
*/
@Deprecated
public void nextFocus() {
- nextFocusHelper();
- }
-
- private boolean nextFocusHelper() {
- Component toFocus = preNextFocusHelper();
+ transferFocus(false);
+ }
+
+ boolean transferFocus(boolean clearOnFailure) {
if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "toFocus = " + toFocus);
- }
- if (isFocusOwner() && toFocus == this) {
- return false;
- }
- return postNextFocusHelper(toFocus, CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
- }
-
- Container getTraversalRoot() {
- return getFocusCycleRootAncestor();
- }
-
- final Component preNextFocusHelper() {
+ focusLog.finer("clearOnFailure = " + clearOnFailure);
+ }
+ Component toFocus = getNextFocusCandidate();
+ boolean res = false;
+ if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
+ res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
+ }
+ if (clearOnFailure && !res) {
+ if (focusLog.isLoggable(Level.FINER)) {
+ focusLog.finer("clear global focus owner");
+ }
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ }
+ if (focusLog.isLoggable(Level.FINER)) {
+ focusLog.finer("returning result: " + res);
+ }
+ return res;
+ }
+
+ final Component getNextFocusCandidate() {
Container rootAncestor = getTraversalRoot();
Component comp = this;
while (rootAncestor != null &&
@@ -7511,18 +7467,19 @@
rootAncestor = comp.getFocusCycleRootAncestor();
}
if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "comp = " + comp + ", root = " + rootAncestor);
- }
+ focusLog.finer("comp = " + comp + ", root = " + rootAncestor);
+ }
+ Component candidate = null;
if (rootAncestor != null) {
FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
Component toFocus = policy.getComponentAfter(rootAncestor, comp);
if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "component after is " + toFocus);
+ focusLog.finer("component after is " + toFocus);
}
if (toFocus == null) {
toFocus = policy.getDefaultComponent(rootAncestor);
if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "default component is " + toFocus);
+ focusLog.finer("default component is " + toFocus);
}
}
if (toFocus == null) {
@@ -7531,23 +7488,12 @@
toFocus = applet;
}
}
- return toFocus;
- }
- return null;
- }
-
- static boolean postNextFocusHelper(Component toFocus, CausedFocusEvent.Cause cause) {
- if (toFocus != null) {
- if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "Next component " + toFocus);
- }
- boolean res = toFocus.requestFocusInWindow(cause);
- if (focusLog.isLoggable(Level.FINER)) {
- focusLog.log(Level.FINER, "Request focus returned " + res);
- }
- return res;
- }
- return false;
+ candidate = toFocus;
+ }
+ if (focusLog.isLoggable(Level.FINER)) {
+ focusLog.finer("Focus transfer candidate: " + candidate);
+ }
+ return candidate;
}
/**
@@ -7557,6 +7503,10 @@
* @since 1.4
*/
public void transferFocusBackward() {
+ transferFocusBackward(false);
+ }
+
+ boolean transferFocusBackward(boolean clearOnFailure) {
Container rootAncestor = getTraversalRoot();
Component comp = this;
while (rootAncestor != null &&
@@ -7567,6 +7517,7 @@
comp = rootAncestor;
rootAncestor = comp.getFocusCycleRootAncestor();
}
+ boolean res = false;
if (rootAncestor != null) {
FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
Component toFocus = policy.getComponentBefore(rootAncestor, comp);
@@ -7574,9 +7525,19 @@
toFocus = policy.getDefaultComponent(rootAncestor);
}
if (toFocus != null) {
- toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
- }
- }
+ res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
+ }
+ }
+ if (!res) {
+ if (focusLog.isLoggable(Level.FINER)) {
+ focusLog.finer("clear global focus owner");
+ }
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ }
+ if (focusLog.isLoggable(Level.FINER)) {
+ focusLog.finer("returning result: " + res);
+ }
+ return res;
}
/**
@@ -7651,6 +7612,20 @@
return hasFocus();
}
+ /*
+ * Used to disallow auto-focus-transfer on disposal of the focus owner
+ * in the process of disposing its parent container.
+ */
+ private boolean autoFocusTransferOnDisposal = true;
+
+ void setAutoFocusTransferOnDisposal(boolean value) {
+ autoFocusTransferOnDisposal = value;
+ }
+
+ boolean isAutoFocusTransferOnDisposal() {
+ return autoFocusTransferOnDisposal;
+ }
+
/**
* Adds the specified popup menu to the component.
* @param popup the popup menu to be added to the component.