JDK-8139581 : AWT components are not drawn after removal and addition to a container
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u105,7u91,8u51,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: generic
  • Submitted: 2015-10-14
  • Updated: 2018-01-02
  • Resolved: 2016-02-02
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.
JDK 8 JDK 9
8u102Fixed 9 b107Fixed
Description
FULL PRODUCT VERSION :
JDK 9 b102, JDK 8u51 b16

ADDITIONAL OS VERSION INFORMATION :
Linux OS

A DESCRIPTION OF THE PROBLEM :
When AWT panel with AWT components, for example "java.awt.Button", is removed from AWT frame and added again to the same frame, then sporadically some AWT components contained in the panel are not drawn, however, clicking in the area of not drawn button leads to drawing of the button.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile and run the test case attached as the file "ComponentIsNotDrawnAfterRemoveAddTest.java".
2. The bug is reproduced, if the test case throws the exception with the message "'paint' method of N components was not called.".
Comments
Found out that a class file instead of a source file was attached as the test case before by mistake. Therefore removing the previously attached "ComponentIsNotDrawnAfterRemoveAddTest.class" file and attaching the correct source file "ComponentIsNotDrawnAfterRemoveAddTest.java".
02-01-2018

The bug was reproduced on 32-bit Linux OS with JDK 9 b102, JDK 8u66 b17, JDK 7u91 b15, JDK 6u105 b15. It was defined that, when the components are not drawn their "java.awt.Component.paint(Graphics)" methods are not called also. REASON OF THE ISSUE: Debugging showed that the bug is caused by switching of "sun.awt.X11.XBaseWindow.initialising" field value from "InitialiseState.INITIALISING" to "InitialiseState.NOT_INITIALISED" before it is set to "InitialiseState.INITIALISED" during initialization of AWT component's peer object in "sun.awt.X11.XBaseWindow.init(XCreateWindowParams)" method. The method "XBaseWindow.init(XCreateWindowParams)" in reduced form looks as: 178 protected final void init(XCreateWindowParams params) { 179 awtLock(); 180 initialising = InitialiseState.INITIALISING; 181 awtUnlock(); ... 184 if (!Boolean.TRUE.equals(params.get(DELAYED))) { 185 preInit(params); 186 create(params); 187 postInit(params); 188 } else { 189 instantPreInit(params); 190 delayedParams = params; 191 } 192 awtLock(); 193 initialising = InitialiseState.INITIALISED; 194 awtLockNotifyAll(); 195 awtUnlock(); ��� So in the begin of "init" method "XBaseWindow.initialising" is set to "INITIALISING", then "XBaseWindow.initialising" is set to "NOT_INITIALISED" during the call "preInit(params);", then the native window is created by "create(params);" call, and in the end of "init" method "XBaseWindow.initialising" is set to "INITIALISED". However, between "create(params);" call and the expression "initialising = InitialiseState.INITIALISED;" X11 "Expose" event addressed to the created native window can arrive to XToolkit as a result of "create(params);" call and not be handled in the method "XBaseWindow.dispatchToWindow(XEvent)" in Toolkit thread, because "XBaseWindow.checkInitialised()" method may return "false", since "XBaseWindow.initialising" field value may still be "NOT_INITIALISED" by this time. And not drawn AWT component is a result of not handling of X11 "Expose" event in the described case. POSSIBLE SOLUTION: The method "XBaseWindow.checkInitialised()" is written in the way that it will block current thread and wait until "XBaseWindow.initialising" becomes "INITIALISED", if it is called, when "XBaseWindow.initialising" equals "INITIALISING". But this scenario never occurs in JDK 9, because "XBaseWindow.initialising" is set to "NOT_INITIALISED" immediately after it is set to "INITIALISING" in "init" method and stays in this state for almost the whole duration of "init" method call. So the solution is to remove "InitialiseState.NOT_INITIALISED" from the code. This change lets the mechanism of waiting for "INITIALISED" state work as designed in the method "checkInitialised".
25-01-2016

The test case was attached to the bug as "ComponentIsNotDrawnAfterRemoveAddTest.java" file.
25-01-2016

The customer is scheduled to go production by the end of December. This is a show-stopper bug for the customer.
19-11-2015