1 /*
2  * Copyright (c) 2012, 2018, 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   @test
26   @key headful
27   @bug 4962534
28   @summary JFrame dances very badly
29   @run main bug4962534
30  */
31 
32 import java.awt.*;
33 import java.awt.event.*;
34 import java.util.Random;
35 import javax.swing.*;
36 
37 public class bug4962534 {
38 
39     Robot robot;
40     volatile Point framePosition;
41     volatile Point newFrameLocation;
42     static JFrame frame;
43     Rectangle gcBounds;
44     Component titleComponent;
45     JLayeredPane lPane;
46     volatile boolean titleFound = false;
47     public static Object LOCK = new Object();
48 
main(final String[] args)49     public static void main(final String[] args) throws Exception {
50         try {
51             bug4962534 app = new bug4962534();
52             app.init();
53             app.start();
54         } finally {
55             if (frame != null) SwingUtilities.invokeAndWait(() -> frame.dispose());
56         }
57     }
58 
init()59     public void init() {
60         try {
61             SwingUtilities.invokeAndWait(new Runnable() {
62                 @Override
63                 public void run() {
64                     createAndShowGUI();
65                 }
66             });
67         } catch (Exception ex) {
68             throw new RuntimeException("Init failed. " + ex.getMessage());
69         }
70     }//End  init()
71 
start()72     public void start() {
73         try {
74             setJLayeredPaneEDT();
75             setTitleComponentEDT();
76         } catch (Exception ex) {
77             ex.printStackTrace();
78             throw new RuntimeException("Test failed. " + ex.getMessage());
79         }
80 
81         if (!titleFound) {
82             throw new RuntimeException("Test Failed. Unable to determine title's size.");
83         }
84 
85         Random r = new Random();
86 
87         for (int iteration = 0; iteration < 10; iteration++) {
88             try {
89                 setFramePosEDT();
90             } catch (Exception ex) {
91                 ex.printStackTrace();
92                 throw new RuntimeException("Test failed.");
93             }
94             try {
95                 robot = new Robot();
96                 robot.setAutoDelay(70);
97 
98                 robot.waitForIdle();
99 
100                 robot.mouseMove(framePosition.x + getJFrameWidthEDT() / 2,
101                         framePosition.y + titleComponent.getHeight() / 2);
102                 robot.mousePress(InputEvent.BUTTON1_MASK);
103 
104                 robot.waitForIdle();
105 
106                 gcBounds =
107                         GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getConfigurations()[0].getBounds();
108 
109                 robot.mouseMove(framePosition.x + getJFrameWidthEDT() / 2,
110                         framePosition.y + titleComponent.getHeight() / 2);
111 
112                 robot.waitForIdle();
113 
114                 int multier = gcBounds.height / 2 - 10; //we will not go out the borders
115                 for (int i = 0; i < 10; i++) {
116                     robot.mouseMove(gcBounds.width / 2 - (int) (r.nextDouble() * multier), gcBounds.height / 2 - (int) (r.nextDouble() * multier));
117                 }
118                 robot.mouseRelease(InputEvent.BUTTON1_MASK);
119 
120                 robot.waitForIdle();
121 
122             } catch (AWTException e) {
123                 throw new RuntimeException("Test Failed. AWTException thrown." + e.getMessage());
124             } catch (Exception e) {
125                 e.printStackTrace();
126                 throw new RuntimeException("Test Failed.");
127             }
128             System.out.println("Mouse  lies in " + MouseInfo.getPointerInfo().getLocation());
129             boolean frameIsOutOfScreen = false;
130             try {
131                 setNewFrameLocationEDT();
132                 System.out.println("Now Frame lies in " + newFrameLocation);
133                 frameIsOutOfScreen = checkFrameIsOutOfScreenEDT();
134             } catch (Exception ex) {
135                 ex.printStackTrace();
136                 throw new RuntimeException("Test Failed.");
137             }
138 
139             if (frameIsOutOfScreen) {
140                 throw new RuntimeException("Test failed. JFrame is out of screen.");
141             }
142 
143         } //for iteration
144         System.out.println("Test passed.");
145     }// start()
146 
createAndShowGUI()147     private void createAndShowGUI() {
148         try {
149             UIManager.setLookAndFeel(
150                     "javax.swing.plaf.metal.MetalLookAndFeel");
151         } catch (Exception ex) {
152             throw new RuntimeException(ex.getMessage());
153         }
154         JFrame.setDefaultLookAndFeelDecorated(true);
155         frame = new JFrame("JFrame Dance Test");
156         frame.pack();
157         frame.setSize(450, 260);
158         frame.setLocationRelativeTo(null);
159         frame.setVisible(true);
160     }
161 
setJLayeredPaneEDT()162     private void setJLayeredPaneEDT() throws Exception {
163 
164         SwingUtilities.invokeAndWait(new Runnable() {
165             @Override
166             public void run() {
167                 lPane = frame.getLayeredPane();
168                 System.out.println("JFrame's LayeredPane " + lPane);
169             }
170         });
171     }
172 
setTitleComponentEDT()173     private void setTitleComponentEDT() throws Exception {
174 
175         SwingUtilities.invokeAndWait(new Runnable() {
176             @Override
177             public void run() {
178                 for (int j = 0; j < lPane.getComponentsInLayer(JLayeredPane.FRAME_CONTENT_LAYER.intValue()).length; j++) {
179                     titleComponent = lPane.getComponentsInLayer(JLayeredPane.FRAME_CONTENT_LAYER.intValue())[j];
180                     if (titleComponent.getClass().getName().equals("javax.swing.plaf.metal.MetalTitlePane")) {
181                         titleFound = true;
182                         break;
183                     }
184                 }
185             }
186         });
187     }
188 
setFramePosEDT()189     private void setFramePosEDT() throws Exception {
190 
191         SwingUtilities.invokeAndWait(new Runnable() {
192             @Override
193             public void run() {
194                 framePosition = frame.getLocationOnScreen();
195             }
196         });
197     }
198 
checkFrameIsOutOfScreenEDT()199     private boolean checkFrameIsOutOfScreenEDT() throws Exception {
200 
201         final boolean[] result = new boolean[1];
202 
203         SwingUtilities.invokeAndWait(new Runnable() {
204             @Override
205             public void run() {
206                 if (newFrameLocation.x > gcBounds.width || newFrameLocation.x < 0
207                     || newFrameLocation.y > gcBounds.height || newFrameLocation.y
208                     < 0) {
209                 result[0] = true;
210             }
211             }
212         });
213         return result[0];
214     }
215 
setNewFrameLocationEDT()216     private void setNewFrameLocationEDT() throws Exception {
217 
218         SwingUtilities.invokeAndWait(new Runnable() {
219             @Override
220             public void run() {
221                 newFrameLocation = new Point(frame.getLocationOnScreen().x
222                         + frame.getWidth() / 2, frame.getLocationOnScreen().y + titleComponent.getHeight() / 2);
223             }
224         });
225     }
226 
getJFrameWidthEDT()227     private int getJFrameWidthEDT() throws Exception {
228 
229         final int[] result = new int[1];
230 
231         SwingUtilities.invokeAndWait(new Runnable() {
232             @Override
233             public void run() {
234                 result[0] = frame.getWidth();
235             }
236         });
237 
238         return result[0];
239     }
240 }// class
241