Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8139581

AWT components are not drawn after removal and addition to a container

    Details

    • Subcomponent:
    • Resolved In Build:
      b107
    • CPU:
      generic
    • OS:
      linux
    • Verification:
      Not verified

      Backports

        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.".

          Activity

          Hide
          tongwan Andrew Wang added a comment -
          The customer is scheduled to go production by the end of December. This is a show-stopper bug for the customer.
          Show
          tongwan Andrew Wang added a comment - The customer is scheduled to go production by the end of December. This is a show-stopper bug for the customer.
          Hide
          alitvinov Anton Litvinov added a comment -
          The test case was attached to the bug as "ComponentIsNotDrawnAfterRemoveAddTest.java" file.
          Show
          alitvinov Anton Litvinov added a comment - The test case was attached to the bug as "ComponentIsNotDrawnAfterRemoveAddTest.java" file.
          Hide
          alitvinov Anton Litvinov added a comment -
          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".
          Show
          alitvinov Anton Litvinov added a comment - 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".
          Hide
          hgupdate HG Updates added a comment -
          URL: http://hg.openjdk.java.net/jdk9/client/jdk/rev/55a81cfbe8be
          User: alitvinov
          Date: 2016-02-02 13:34:56 +0000
          Show
          hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/client/jdk/rev/55a81cfbe8be User: alitvinov Date: 2016-02-02 13:34:56 +0000
          Hide
          hgupdate HG Updates added a comment -
          URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/55a81cfbe8be
          User: lana
          Date: 2016-02-24 20:06:43 +0000
          Show
          hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/55a81cfbe8be User: lana Date: 2016-02-24 20:06:43 +0000

            People

            • Assignee:
              alitvinov Anton Litvinov
              Reporter:
              shadowbug Shadow Bug
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: