1 
   2 /*
   3  * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * @test
  27  * @key headful
  28  * @bug 8139581
  29  * @summary AWT components are not drawn after removal and addition to a container
  30  * @author Anton Litvinov
  31  */
  32 
  33 import java.awt.Button;
  34 import java.awt.Color;
  35 import java.awt.Canvas;
  36 import java.awt.Frame;
  37 import java.awt.Graphics;
  38 import java.awt.Panel;
  39 import java.util.ArrayList;
  40 
  41 public class ComponentIsNotDrawnAfterRemoveAddTest {
  42     private final Frame frame;
  43     private final Panel panel;
  44     private final ArrayList<Testable> compList = new ArrayList<Testable>();
  45 
  46     public ComponentIsNotDrawnAfterRemoveAddTest() {
  47         frame = new Frame("ComponentIsNotDrawnAfterRemoveAddTest");
  48         frame.setSize(500, 500);
  49         frame.setLocation(200, 200);
  50         frame.setLayout(null);
  51         frame.setBackground(Color.RED);
  52 
  53         panel = new Panel();
  54         panel.setLayout(null);
  55         panel.setBounds(25, 100, 455, 295);
  56         panel.setBackground(Color.GREEN);
  57 
  58         for (int i = 0; i < 10; i++) {
  59             TestCanvas canv1 = new TestCanvas();
  60             canv1.setBounds(i * 45 + 5, 15, 30 + i, 30 + i);
  61             panel.add(canv1);
  62             compList.add(canv1);
  63 
  64             TestButton btn1 = new TestButton();
  65             btn1.setBounds(i * 45 + 5, 60, 30 + i, 30 + i);
  66             panel.add(btn1);
  67             compList.add(btn1);
  68 
  69             TestCanvas canv2 = new TestCanvas();
  70             canv2.setBounds(i * 45 + 5, 105, 30 + i, 30 + i);
  71             panel.add(canv2);
  72             compList.add(canv2);
  73 
  74             TestButton btn2 = new TestButton();
  75             btn2.setBounds(i * 45 + 5, 150, 30 + i, 30 + i);
  76             panel.add(btn2);
  77             compList.add(btn2);
  78 
  79             TestCanvas canv3 = new TestCanvas();
  80             canv3.setBounds(i * 45 + 5, 195, 30 + i, 30 + i);
  81             panel.add(canv3);
  82             compList.add(canv3);
  83 
  84             TestButton btn3 = new TestButton();
  85             btn3.setBounds(i * 45 + 5, 240, 30 + i, 30 + i);
  86             panel.add(btn3);
  87             compList.add(btn3);
  88         }
  89 
  90         frame.add(panel);
  91         frame.setVisible(true);
  92     }
  93 
  94     private void runTest() {
  95         try {
  96             doSleep(1500);
  97             checkTestableComponents();
  98 
  99             for (int i = 0; i < 5; i++) {
 100                 System.err.println(String.format("Test iteration #%d:", i));
 101 
 102                 frame.remove(panel);
 103                 frame.invalidate();
 104                 frame.validate();
 105                 frame.add(panel);
 106 
 107                 doSleep(1500);
 108                 checkTestableComponents();
 109             }
 110         } finally {
 111             frame.dispose();
 112         }
 113     }
 114 
 115     private void doSleep(long millis) {
 116         try {
 117             Thread.sleep(millis);
 118         } catch (InterruptedException ie) {
 119             ie.printStackTrace();
 120         }
 121     }
 122 
 123     private void checkTestableComponents() throws RuntimeException {
 124         int notDrawnCompsCount = 0;
 125         for (Testable comp : compList) {
 126             if (!comp.wasPaintCalled()) {
 127                 notDrawnCompsCount++;
 128             } else {
 129                 comp.resetPaintCalledFlag();
 130             }
 131         }
 132         if (notDrawnCompsCount > 0) {
 133             throw new RuntimeException(String.format(
 134                 "'paint' method of %d components was not called.", notDrawnCompsCount));
 135         }
 136     }
 137 
 138     private interface Testable {
 139         boolean wasPaintCalled();
 140         void resetPaintCalledFlag();
 141     }
 142 
 143     private static class TestCanvas extends Canvas implements Testable {
 144         private volatile boolean paintWasCalled = false;
 145 
 146         @Override
 147         public void paint(Graphics g) {
 148             paintWasCalled = true;
 149             super.paint(g);
 150             g.setColor(Color.BLUE);
 151             g.fillRect(0, 0, getWidth(), getHeight());
 152         }
 153 
 154         @Override
 155         public boolean wasPaintCalled() {
 156             return paintWasCalled;
 157         }
 158 
 159         @Override
 160         public void resetPaintCalledFlag() {
 161             paintWasCalled = false;
 162         }
 163     }
 164 
 165     private static class TestButton extends Button implements Testable {
 166         private volatile boolean paintWasCalled = false;
 167 
 168         @Override
 169         public void paint(Graphics g) {
 170             paintWasCalled = true;
 171             super.paint(g);
 172             g.setColor(Color.YELLOW);
 173             g.fillRect(0, 0, 15, 15);
 174         }
 175 
 176         @Override
 177         public boolean wasPaintCalled() {
 178             return paintWasCalled;
 179         }
 180 
 181         @Override
 182         public void resetPaintCalledFlag() {
 183             paintWasCalled = false;
 184         }
 185     }
 186 
 187     public static void main(String[] args) {
 188         new ComponentIsNotDrawnAfterRemoveAddTest().runTest();
 189     }
 190 }