JDK-7125044 : [macosx] Test failure because Component.transferFocus() works differently in applet and application.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: os_x
  • CPU: x86
  • Submitted: 2011-12-26
  • Updated: 2014-01-23
  • Resolved: 2012-04-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7u4 b18Fixed 8Fixed
Related Reports
Relates :  
Relates :  
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.

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.

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.

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

EVALUATION To reproduce in applet mode the provided policy should be set: $JAVA_HOME/bin/appletviewer -J-Djava.security.policy=awt.policy TransferF6.html