1/*
2 * Copyright (c) 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 @test
26 @key headful
27 @bug 7126823
28 @summary Verify NormalBounds upon iconify/deiconify sequence
29 @run main NormalBoundsTest
30 */
31import java.awt.Point;
32import java.awt.Rectangle;
33import java.awt.Robot;
34import java.awt.event.InputEvent;
35import java.beans.PropertyVetoException;
36import javax.swing.JDesktopPane;
37import javax.swing.JFrame;
38import javax.swing.JInternalFrame;
39import javax.swing.SwingUtilities;
40import javax.swing.UIManager;
41import javax.swing.UnsupportedLookAndFeelException;
42import javax.swing.WindowConstants;
43
44public class NormalBoundsTest {
45
46    private static JFrame mainFrame;
47    private static JInternalFrame internalFrame;
48    private static Rectangle bounds;
49
50    private static void createUI(String lookAndFeelString) {
51        internalFrame = new JInternalFrame("Internal", true, true, true, true);
52        internalFrame.setDefaultCloseOperation(
53                WindowConstants.DO_NOTHING_ON_CLOSE);
54        internalFrame.setSize(200, 200);
55
56        JDesktopPane desktopPane = new JDesktopPane();
57        desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
58        desktopPane.add(internalFrame);
59
60        mainFrame = new JFrame(lookAndFeelString);
61        mainFrame.setSize(640, 480);
62        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
63        mainFrame.setContentPane(desktopPane);
64
65        mainFrame.setVisible(true);
66        internalFrame.setVisible(true);
67
68    }
69
70    private static int signWOZero(int i) {
71        return (i > 0) ? 1 : -1;
72    }
73
74    private static void mouseMove(Robot robot, Point startPt, Point endPt) {
75        int dx = endPt.x - startPt.x;
76        int dy = endPt.y - startPt.y;
77
78        int ax = Math.abs(dx) * 2;
79        int ay = Math.abs(dy) * 2;
80
81        int sx = signWOZero(dx);
82        int sy = signWOZero(dy);
83
84        int x = startPt.x;
85        int y = startPt.y;
86
87        int d = 0;
88
89        if (ax > ay) {
90            d = ay - ax / 2;
91            while (true) {
92                robot.mouseMove(x, y);
93                robot.delay(50);
94
95                if (x == endPt.x) {
96                    return;
97                }
98                if (d >= 0) {
99                    y = y + sy;
100                    d = d - ax;
101                }
102                x = x + sx;
103                d = d + ay;
104            }
105        } else {
106            d = ax - ay / 2;
107            while (true) {
108                robot.mouseMove(x, y);
109                robot.delay(50);
110
111                if (y == endPt.y) {
112                    return;
113                }
114                if (d >= 0) {
115                    x = x + sx;
116                    d = d - ay;
117                }
118                y = y + sy;
119                d = d + ax;
120            }
121        }
122    }
123
124    private static void drag(Robot r, Point startPt, Point endPt, int button) {
125        if (!(button == InputEvent.BUTTON1_MASK
126                || button == InputEvent.BUTTON2_MASK
127                || button == InputEvent.BUTTON3_MASK)) {
128            throw new IllegalArgumentException("invalid mouse button");
129        }
130
131        r.mouseMove(startPt.x, startPt.y);
132        r.mousePress(button);
133        try {
134            mouseMove(r, startPt, endPt);
135        } finally {
136            r.mouseRelease(button);
137        }
138    }
139
140    private static boolean tryLookAndFeel(String lookAndFeelString) {
141        try {
142            UIManager.setLookAndFeel(lookAndFeelString);
143            return true;
144        } catch (UnsupportedLookAndFeelException | ClassNotFoundException |
145                InstantiationException | IllegalAccessException e) {
146            return false;
147        }
148    }
149
150    public static void executeTest(Robot robot) throws Exception {
151
152        // Iconize JInternalFrame
153        SwingUtilities.invokeAndWait(new Runnable() {
154            @Override
155            public void run() {
156                try {
157                    internalFrame.setIcon(true);
158                } catch (PropertyVetoException ex) {
159                    mainFrame.dispose();
160                    throw new RuntimeException("Iconize InternalFrame Failed");
161                }
162            }
163        });
164        robot.waitForIdle();
165
166        // Deiconize JInternalFrame
167        SwingUtilities.invokeAndWait(new Runnable() {
168            @Override
169            public void run() {
170                try {
171                    internalFrame.setIcon(false);
172                } catch (PropertyVetoException ex) {
173                    mainFrame.dispose();
174                    throw new RuntimeException("Deiconize InternalFrame"
175                            + " Failed");
176                }
177            }
178        });
179        robot.waitForIdle();
180
181        SwingUtilities.invokeAndWait(new Runnable() {
182            @Override
183            public void run() {
184                Point loc = internalFrame.getLocationOnScreen();
185                // Drag Frame
186                drag(robot,
187                        new Point((int) loc.x + 80, (int) loc.y + 12),
188                        new Point((int) loc.x + 100, (int) loc.y + 40),
189                        InputEvent.BUTTON1_MASK);
190            }
191        });
192        robot.waitForIdle();
193
194        SwingUtilities.invokeAndWait(new Runnable() {
195            @Override
196            public void run() {
197                bounds = internalFrame.getBounds();
198                if (!internalFrame.getNormalBounds().equals(bounds)) {
199                    mainFrame.dispose();
200                    throw new RuntimeException("Invalid NormalBounds");
201                }
202            }
203        });
204        robot.waitForIdle();
205
206        // Regression Test Bug ID: 4424247
207        // Maximize JInternalFrame
208        SwingUtilities.invokeAndWait(new Runnable() {
209            @Override
210            public void run() {
211                try {
212                    internalFrame.setMaximum(true);
213                } catch (PropertyVetoException ex) {
214                    mainFrame.dispose();
215                    throw new RuntimeException("Maximize InternalFrame Failed");
216                }
217            }
218        });
219        robot.waitForIdle();
220
221        // Iconize JInternalFrame
222        SwingUtilities.invokeAndWait(new Runnable() {
223            @Override
224            public void run() {
225                try {
226                    internalFrame.setIcon(true);
227                } catch (PropertyVetoException ex) {
228                    mainFrame.dispose();
229                    throw new RuntimeException("Iconize InternalFrame Failed");
230                }
231            }
232        });
233        robot.waitForIdle();
234
235        // DeIconize JInternalFrame
236        SwingUtilities.invokeAndWait(new Runnable() {
237            @Override
238            public void run() {
239                try {
240                    internalFrame.setIcon(false);
241                } catch (PropertyVetoException ex) {
242                    mainFrame.dispose();
243                    throw new RuntimeException("DeIcoize InternalFrame "
244                            + " Failed");
245                }
246            }
247        });
248        robot.waitForIdle();
249
250        // Restore/Undo Maximize JInternalFrame
251        SwingUtilities.invokeAndWait(new Runnable() {
252            @Override
253            public void run() {
254                try {
255                    internalFrame.setMaximum(false);
256                } catch (PropertyVetoException ex) {
257                    mainFrame.dispose();
258                    throw new RuntimeException("Restore InternalFrame "
259                            + " Failed");
260                }
261            }
262        });
263        robot.waitForIdle();
264
265        SwingUtilities.invokeAndWait(new Runnable() {
266            @Override
267            public void run() {
268                if (!internalFrame.getBounds().equals(bounds)) {
269                    mainFrame.dispose();
270                    throw new RuntimeException("Regression Test Failed");
271                }
272            }
273        });
274        robot.waitForIdle();
275
276        mainFrame.dispose();
277    }
278
279    public static void main(String[] args) throws Exception {
280        Robot robot = new Robot();
281        UIManager.LookAndFeelInfo[] lookAndFeelArray
282                = UIManager.getInstalledLookAndFeels();
283        for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
284            String lookAndFeelString = lookAndFeelItem.getClassName();
285            if (tryLookAndFeel(lookAndFeelString)) {
286                // create UI
287                SwingUtilities.invokeAndWait(new Runnable() {
288                    @Override
289                    public void run() {
290                        createUI(lookAndFeelString);
291                    }
292                });
293
294                robot.waitForIdle();
295                executeTest(robot);
296            } else {
297                throw new RuntimeException("Setting Look and Feel Failed");
298            }
299        }
300
301    }
302}
303