United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7125044 [macosx] Test failure because Component.transferFocus() works differently in applet and application.
JDK-7125044 : [macosx] Test failure because Component.transferFocus() works differently in applet and application.

Details
Type:
Bug
Submit Date:
2011-12-26
Status:
Closed
Updated Date:
2014-01-23
Project Name:
JDK
Resolved Date:
2012-04-04
Component:
client-libs
OS:
os_x
Sub-Component:
java.awt
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
7u4 (b18)

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
Run the attached minimal example as an application and as an applet. It will rather slowly transfer focus to and fro using focusNext/PreviousComponent of KFM and transferFocus() of the Component. You will see that final focused component will be different for applet and application.

I have some tests failing on Mac for exactly that reason: button.transferFocus() called from a last child component in a Frame (not that button), when running as an applet, would transfer not to a next component after button but to the button itself.

Perhaps this behaviour is someway expected but it isn't clear from a specification. And then, the tests don't expect it, and they usually pass on the other platforms.

Yet another detail: an example works not on EDT as in the real test, however the real test fails on EDT just the same.

                                    

Comments
SUGGESTED FIX

http://cr.openjdk.java.net/~ant/7125044/webrev.1/

In the fix it's assumed that swing toplevel initialization process initiates JRootPane
creation which in its turn updates UI where swing layout focus policy is eventually set.
For exmple, for JFrame the stack looks as follows: 

	at javax.swing.UIManager.maybeInitializeFocusPolicy(UIManager.java:1440)
	at javax.swing.UIManager.getUI(UIManager.java:1004)
	at javax.swing.JRootPane.updateUI(JRootPane.java:483)
	at javax.swing.JRootPane.<init>(JRootPane.java:370)
	at javax.swing.JFrame.createRootPane(JFrame.java:277)
	at javax.swing.JFrame.frameInit(JFrame.java:258)
	at javax.swing.JFrame.<init>(JFrame.java:181)

Also the fix eliminates the code in SunToolkit.checkAndSetPolicy(..) that determined
focus traversal policy for XAWT container. Now the policy is taken from KeyboardFocusManager
strictly following javadoc.

All four tests below pass with the fix:

AWT_Focus/Automated/Lw/ProgrammaticTraversalTest/ProgrammaticTraversalTest.html
AWT_Focus/Automated/Mw/ProgrammaticTraversalTest/ProgrammaticTraversalTest.html
AWT_Focus/Automated/Swing/ProgrammaticTraversalTest/ProgrammaticTraversalTest.html
AWT_Focus/Automated/AWT/ProgrammaticTraversalTest/ProgrammaticTraversalTest.html
                                     
2012-02-27
EVALUATION

To reproduce in applet mode the provided policy should be set:

$JAVA_HOME/bin/appletviewer -J-Djava.security.policy=awt.policy TransferF6.html
                                     
2012-02-21
EVALUATION

Quite interesting. The reason of the failure is focus traversal policy (FTP).
LWAWT toolkit uses swing delegates which lauches swing machinery.
UIManager.initialize() sets swing's default layout FTP onto KeyboardFocusManager.
The latter is taken by toplevel on its initialization (init() method) by calling

SunToolkit.checkAndSetPolicy(boolean, boolean);

So, when first LWAWT toplevel in the app is initialized it takes default AWT FTP
Then components are created and UIManager.initialize() is called. Thus, when second
toplevel (and all subsequent ones) is initialized it takes default swing FTP.

The testcase in applet mode runs two toplevels: AppletViewer & the test Frame.
So, the frame is initialized with swing FTP whereas when it's run as standalone
it picks AWT FTP. That's the difference in focus traversal behavior.
                                     
2012-02-27
EVALUATION

Both UIManager.initialize() & SunToolkit.checkAndSetPolicy(..) has a check for XToolkit,
which uses swing delegates conception as well as LWToolkit. For XToolkit, UIManager doesn't
set swing FTP but SunToolkit specially calculates which FTP should be set on an awt or swing
XAWT container.

The easiest fix would be to do the same for LWAWT. However, I don't like the idea of hardcoding
toolkit names. Instead, we could change the logic when an application is considered to be
a Swing app or a Mixed app (in both cases swing layout FTP should be used). Suppose that
the criteria is a swing toplevel initialization.

Thus we have to detect when a swing toplevel is being initialized and only then set swing FTP.
This would eliminate the need to know which toolkit the app belongs to.
                                     
2012-02-27



Hardware and Software, Engineered to Work Together