1 /*
2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 import java.awt.*;
26 import java.awt.event.InputEvent;
27 import javax.swing.*;
28 import java.io.*;
29 import test.java.awt.regtesthelpers.Util;
30 
31 /**
32  * AWT/Swing overlapping test for Panel and JPanel behavior during resizing.
33  * <p>See <a href="https://bugs.openjdk.java.net/browse/JDK-6786219">JDK-6786219</a> for details
34  */
35 /*
36  * @test
37  * @key headful
38  * @bug 6786219 8221823
39  * @summary Issues when resizing the frame after mixing of heavy weight & light weight components
40  * @author sergey.grinev@oracle.com: area=awt.mixing
41  * @library ../../regtesthelpers
42  * @build Util
43  * @build FrameBorderCounter
44  * @run main MixingPanelsResizing
45  */
46 public class MixingPanelsResizing {
47 
48     static volatile boolean failed = false;
49 
50     private static JFrame frame;
51     private static JButton jbutton;
52     private static Button awtButton;
53     private static JButton jbutton2;
54     private static Button awtButton2;
55     private static final Color jbColor = Color.RED;
56     private static final Color awtColor = Color.ORANGE;
57     private static final Color jb2Color = Color.BLUE;
58     private static final Color awt2Color = Color.CYAN;
59     private static final int ROBOT_DELAY = 500;
60 
61     private static Point lLoc;
62     private static int borderShift;
63 
frameBorderCounter()64     private static int frameBorderCounter() {
65         String JAVA_HOME = System.getProperty("java.home");
66         try {
67             Process p = Runtime.getRuntime().exec(JAVA_HOME + "/bin/java FrameBorderCounter");
68             try {
69                 p.waitFor();
70             } catch (InterruptedException e) {
71                 e.printStackTrace();
72                 throw new RuntimeException(e);
73             }
74             if (p.exitValue() != 0) {
75                 throw new RuntimeException("FrameBorderCounter exited with not null code!\n" + readInputStream(p.getErrorStream()));
76             }
77             return Integer.parseInt(readInputStream(p.getInputStream()).trim());
78         } catch (IOException e) {
79             e.printStackTrace();
80             throw new RuntimeException(e);
81         }
82     }
83 
readInputStream(InputStream is)84     private static String readInputStream(InputStream is) throws IOException {
85         byte[] buffer = new byte[4096];
86         int len = 0;
87         StringBuilder sb = new StringBuilder();
88         try (InputStreamReader isr = new InputStreamReader(is)) {
89             while ((len = is.read(buffer)) > 0) {
90                 sb.append(new String(buffer, 0, len));
91             }
92         }
93         return sb.toString();
94     }
95 
init()96     private static void init() throws Exception {
97         //*** Create instructions for the user here ***
98 
99         borderShift = frameBorderCounter();
100         borderShift = Math.abs(borderShift) == 1 ? borderShift : (borderShift / 2);
101         SwingUtilities.invokeAndWait(new Runnable() {
102             public void run() {
103                 // prepare controls
104 
105                 frame = new JFrame();
106 
107                 Panel awtPanel = new Panel();
108                 awtPanel.setBackground(Color.GREEN);
109                 awtButton = new Button("AWTButton");
110                 awtPanel.add(awtButton);
111                 awtButton.setForeground(awtColor);
112                 awtButton.setBackground(awtColor);
113                 jbutton = new JButton("SwingButton");
114                 awtPanel.add(jbutton);
115                 jbutton.setForeground(jbColor);
116                 jbutton.setBackground(jbColor);
117 
118                 JPanel jPanel = new JPanel();
119                 jbutton2 = new JButton("SwingButton2");
120                 jPanel.add(jbutton2);
121                 jbutton2.setForeground(jb2Color);
122                 jbutton2.setBackground(jb2Color);
123                 awtButton2 = new Button("AWT Button2");
124                 jPanel.add(awtButton2);
125                 awtButton2.setForeground(awt2Color);
126                 awtButton2.setBackground(awt2Color);
127                 jPanel.setBackground(Color.YELLOW);
128 
129                 frame.add(awtPanel, BorderLayout.SOUTH);
130                 frame.add(jPanel, BorderLayout.NORTH);
131 
132                 frame.pack();
133                 frame.setVisible(true);
134             }
135         });
136 
137         /////////////////////////
138 
139         final Robot robot = Util.createRobot();
140         robot.setAutoDelay(ROBOT_DELAY);
141 
142         Util.waitForIdle(robot);
143 
144         SwingUtilities.invokeAndWait(new Runnable() {
145             public void run() {
146                 lLoc = frame.getLocationOnScreen();
147                 lLoc.translate(frame.getWidth() + borderShift, frame.getHeight() + borderShift);
148             }
149         });
150 
151         //grow
152         robot.mouseMove(lLoc.x, lLoc.y);
153         robot.mousePress(InputEvent.BUTTON1_MASK);
154 
155         Runnable test = new Runnable() {
156 
157             public void run() {
158                 Point btnLoc = jbutton.getLocationOnScreen();
159                 Color c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5);
160                 if (!c.equals(jbColor)) {
161                     fail("JButton was not redrawn properly on AWT Panel during move");
162                 }
163 
164                 btnLoc = awtButton.getLocationOnScreen();
165                 c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5);
166                 if (!c.equals(awtColor)) {
167                     fail("AWT Button was not redrawn properly on AWT Panel during move");
168                 }
169 
170                 btnLoc = jbutton2.getLocationOnScreen();
171                 c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5);
172                 if (!c.equals(jb2Color)) {
173                     fail("JButton was not redrawn properly on JPanel during move");
174                 }
175 
176                 btnLoc = awtButton2.getLocationOnScreen();
177                 c = robot.getPixelColor(btnLoc.x + 5, btnLoc.y + 5);
178                 if (!c.equals(awt2Color)) {
179                     fail("ATW Button was not redrawn properly on JPanel during move");
180                 }
181             }
182         };
183 
184         for (int i = 0; i < 30; i++) {
185             test.run();
186             robot.mouseMove(lLoc.x + 20 * i, lLoc.y + 10 * i);
187         }
188         robot.mouseRelease(InputEvent.BUTTON1_MASK);
189 
190         //back
191         System.out.println("fast back");
192         robot.mousePress(InputEvent.BUTTON1_MASK);
193         for (int i = 5; i >= 0; i--) {
194             test.run();
195             robot.mouseMove(lLoc.x + 120 * i, lLoc.y + 60 * i);
196         }
197         robot.mouseRelease(InputEvent.BUTTON1_MASK);
198 
199         pass();
200     }//End  init()
201     /*****************************************************
202      * Standard Test Machinery Section
203      * DO NOT modify anything in this section -- it's a
204      * standard chunk of code which has all of the
205      * synchronisation necessary for the test harness.
206      * By keeping it the same in all tests, it is easier
207      * to read and understand someone else's test, as
208      * well as insuring that all tests behave correctly
209      * with the test harness.
210      * There is a section following this for test-
211      * classes
212      ******************************************************/
213     private static boolean theTestPassed = false;
214     private static boolean testGeneratedInterrupt = false;
215     private static String failureMessage = "";
216     private static Thread mainThread = null;
217     private static int sleepTime = 300000;
218 
219     // Not sure about what happens if multiple of this test are
220     //  instantiated in the same VM.  Being static (and using
221     //  static vars), it aint gonna work.  Not worrying about
222     //  it for now.
main(String args[])223     public static void main(String args[]) throws Exception {
224         if (!Toolkit.getDefaultToolkit().isDynamicLayoutActive()) {
225             System.out.println("Dynamic layout is not active. Test passes.");
226             return;
227         }
228         mainThread = Thread.currentThread();
229         try {
230             init();
231         } catch (TestPassedException e) {
232             //The test passed, so just return from main and harness will
233             // interepret this return as a pass
234             return;
235         }
236         //At this point, neither test pass nor test fail has been
237         // called -- either would have thrown an exception and ended the
238         // test, so we know we have multiple threads.
239 
240         //Test involves other threads, so sleep and wait for them to
241         // called pass() or fail()
242         try {
243             Thread.sleep(sleepTime);
244             //Timed out, so fail the test
245             throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds");
246         } catch (InterruptedException e) {
247             //The test harness may have interrupted the test.  If so, rethrow the exception
248             // so that the harness gets it and deals with it.
249             if (!testGeneratedInterrupt) {
250                 throw e;
251             }
252 
253             //reset flag in case hit this code more than once for some reason (just safety)
254             testGeneratedInterrupt = false;
255 
256             if (theTestPassed == false) {
257                 throw new RuntimeException(failureMessage);
258             }
259         }
260 
261     }//main
262 
setTimeoutTo(int seconds)263     public static synchronized void setTimeoutTo(int seconds) {
264         sleepTime = seconds * 1000;
265     }
266 
pass()267     public static synchronized void pass() {
268         System.out.println("The test passed.");
269         System.out.println("The test is over, hit  Ctl-C to stop Java VM");
270         //first check if this is executing in main thread
271         if (mainThread == Thread.currentThread()) {
272             //Still in the main thread, so set the flag just for kicks,
273             // and throw a test passed exception which will be caught
274             // and end the test.
275             theTestPassed = true;
276             throw new TestPassedException();
277         }
278         theTestPassed = true;
279         testGeneratedInterrupt = true;
280         mainThread.interrupt();
281     }//pass()
282 
fail()283     public static synchronized void fail() {
284         //test writer didn't specify why test failed, so give generic
285         fail("it just plain failed! :-)");
286     }
287 
fail(String whyFailed)288     public static synchronized void fail(String whyFailed) {
289         System.out.println("The test failed: " + whyFailed);
290         System.out.println("The test is over, hit  Ctl-C to stop Java VM");
291         //check if this called from main thread
292         if (mainThread == Thread.currentThread()) {
293             //If main thread, fail now 'cause not sleeping
294             throw new RuntimeException(whyFailed);
295         }
296         theTestPassed = false;
297         testGeneratedInterrupt = true;
298         failureMessage = whyFailed;
299         mainThread.interrupt();
300     }//fail()
301 }// class JButtonInGlassPane
302 class TestPassedException extends RuntimeException {
303 }
304