United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7081012 REGRESSION:Component.transferFocusBackward invokes clearGlobalFocusOwner()
JDK-7081012 : REGRESSION:Component.transferFocusBackward invokes clearGlobalFocusOwner()

Details
Type:
Bug
Submit Date:
2011-08-19
Status:
Resolved
Updated Date:
2013-12-06
Project Name:
JDK
Resolved Date:
2011-09-20
Component:
client-libs
OS:
windows_xp
Sub-Component:
java.awt
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Any OS running Java 7. For example: Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Using Java 1.7, my custom LayoutFocusTraversalPolicy no longer works properly when I press Shift-Tab in my custom Component.

* Pressing Tab to possibly transfer the focus to the next Component works fine.
* Pressing Shift-Tab  to possibly transfer the focus to the previous Component causes my application to completely loose the keyboard focus.
* Everything used to work fine with Java 1.5 and Java 1.6.

After looking at the Java 1.7 source code of java.awt.Component, I've spotted the problem. It's
transferFocusBackward(boolean clearOnFailure) which (unlike  transferFocus(boolean clearOnFailure)), completely ignores the value of parameter clearOnFailure and incorrectly invokes  KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner().

In:
-----------------------------------------------------------------------------------------------------------------
public void transferFocusBackward() {
    transferFocusBackward(false);
}

boolean transferFocusBackward(boolean clearOnFailure) {
    Container rootAncestor = getTraversalRoot();
    Component comp = this;
    while (rootAncestor != null &&
           !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
    {
        comp = rootAncestor;
        rootAncestor = comp.getFocusCycleRootAncestor();
    }
    boolean res = false;
    if (rootAncestor != null) {
        FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
        Component toFocus = policy.getComponentBefore(rootAncestor, comp);
        if (toFocus == null) {
            toFocus = policy.getDefaultComponent(rootAncestor);
        }
        if (toFocus != null) {
            res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
        }
    }
    if (!res) {
        if (focusLog.isLoggable(PlatformLogger.FINER)) {
            focusLog.finer("clear global focus owner");
        }
        KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
    }
    if (focusLog.isLoggable(PlatformLogger.FINER)) {
        focusLog.finer("returning result: " + res);
    }
    return res;
}
-----------------------------------------------------------------------------------------------------------------
replacing:
-----------------------------------------------------------------------------------------------------------------
    if (!res) {
-----------------------------------------------------------------------------------------------------------------
by:
-----------------------------------------------------------------------------------------------------------------
    if (clearOnFailure && !res) {
-----------------------------------------------------------------------------------------------------------------
should fix this regression.

REGRESSION.  Last worked in version 6u26

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Not useful. The bug is obvious. Suffice to read the source code of  Component.transferFocusBackward(boolean clearOnFailure).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Not useful. The bug is obvious. Suffice to read the source code of  Component.transferFocusBackward(boolean clearOnFailure).
ACTUAL -
Not useful. The bug is obvious. Suffice to read thesource  code of  Component.transferFocusBackward(boolean clearOnFailure).

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Not useful. The bug is obvious. Suffice to read the source code of  Component.transferFocusBackward(boolean clearOnFailure).

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Not useful. The bug is obvious. Suffice to read the source code of  Component.transferFocusBackward(boolean clearOnFailure).
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Redefine Component.transferFocusBackward in my custom component. I more or less copied the code from Component.java after fixing this bug.

                                    

Comments
EVALUATION

Sounds reasonable.
                                     
2011-09-01



Hardware and Software, Engineered to Work Together