1/*
2 * Copyright (c) 2007, 2014, 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
24import static jdk.testlibrary.Asserts.*;
25
26import java.awt.*;
27import java.util.List;
28import java.util.ArrayList;
29
30public class BlockingWindowsTest {
31
32    private TestDialog dialog, childDialog, secondDialog, dummyDialog, parentDialog;
33    private TestFrame frame, secondFrame;
34    private TestWindow window, childWindow;
35
36    private static final int delay = 500;
37    private final ExtendedRobot robot;
38
39    private List<Window> allWindows;
40
41    private Dialog hiddenDialog;
42    private Frame  hiddenFrame;
43
44    private Dialog.ModalityType modalityType;
45
46    public enum DialogOwner {HIDDEN_DIALOG, NULL_DIALOG, HIDDEN_FRAME, NULL_FRAME, DIALOG, FRAME};
47
48    private BlockingWindowsTest(Dialog.ModalityType modType,
49                                boolean             setModal,
50                                DialogOwner         owner) throws Exception {
51
52        modalityType = modType;
53        robot = new ExtendedRobot();
54        EventQueue.invokeLater(() -> {
55            createGUI(setModal, owner);
56        });
57    }
58
59    public BlockingWindowsTest(
60            Dialog.ModalityType modalityType, DialogOwner owner) throws Exception {
61        this(modalityType, false, owner);
62    }
63
64    public BlockingWindowsTest(DialogOwner owner) throws Exception {
65        this(null, true, owner);
66    }
67
68    private void createGUI(boolean     setModal,
69                           DialogOwner owner) {
70
71        allWindows = new ArrayList<>();
72
73        if (owner != DialogOwner.DIALOG) {
74            frame = new CustomFrame();
75            frame.setLocation(50, 50);
76            frame.setVisible(true);
77            allWindows.add(frame);
78        }
79
80        switch (owner) {
81            case DIALOG:
82                parentDialog = new ParentDialog((Dialog) null);
83                parentDialog.setLocation(50, 50);
84                parentDialog.setVisible(true);
85                allWindows.add(parentDialog);
86                dialog = new CustomDialog(parentDialog);
87                break;
88            case FRAME:
89                dialog = new CustomDialog(frame);
90                break;
91            case HIDDEN_DIALOG:
92                hiddenDialog = new Dialog((Frame) null);
93                dialog = new CustomDialog(hiddenDialog);
94                allWindows.add(hiddenDialog);
95                break;
96            case NULL_DIALOG:
97                dialog = new CustomDialog((Dialog) null);
98                break;
99            case HIDDEN_FRAME:
100                hiddenFrame = new Frame();
101                dialog = new CustomDialog(hiddenFrame);
102                allWindows.add(hiddenFrame);
103                break;
104            case NULL_FRAME:
105                dialog = new CustomDialog((Frame) null);
106                break;
107        }
108
109        assertFalse(dialog == null, "error: null dialog");
110
111        if (setModal) {
112            dialog.setModal(true);
113        } else if (modalityType != null) {
114            dialog.setModalityType(modalityType);
115        }
116
117        dialog.setLocation(250, 50);
118        allWindows.add(dialog);
119
120        if (owner == DialogOwner.DIALOG) {
121            window = new TestWindow(parentDialog);
122        } else {
123            window = new TestWindow(frame);
124        }
125
126        window.setLocation(50, 250);
127        allWindows.add(window);
128
129        if (owner == DialogOwner.DIALOG) {
130            dummyDialog = new TestDialog(parentDialog);
131        } else {
132            dummyDialog = new TestDialog(frame);
133        }
134        dummyDialog.setLocation(450, 450);
135        allWindows.add(dummyDialog);
136
137        childWindow = new CustomWindow(dialog);
138        childWindow.setLocation(450, 50);
139        allWindows.add(childWindow);
140
141        childDialog = new TestDialog(dialog);
142        childDialog.setLocation(450, 250);
143        allWindows.add(childDialog);
144
145        if (owner == DialogOwner.DIALOG) {
146            secondDialog = new CustomDialog(parentDialog);
147        } else {
148            secondDialog = new CustomDialog(frame);
149        }
150        if (setModal) {
151            secondDialog.setModal(true);
152        } else if (modalityType != null) {
153            secondDialog.setModalityType(modalityType);
154        }
155
156        secondDialog.setLocation(50, 450);
157        allWindows.add(secondDialog);
158
159        secondFrame = new TestFrame();
160        secondFrame.setLocation(250, 450);
161        allWindows.add(secondFrame);
162    }
163
164    public void doTest() throws Exception {
165
166        try {
167
168            robot.waitForIdle(delay);
169
170            if (parentDialog == null) { frame.clickOpenButton(robot); }
171            else { parentDialog.clickOpenButton(robot); }
172            robot.waitForIdle(delay);
173
174            dialog.activated.waitForFlagTriggered();
175            assertTrue(dialog.activated.flag(), "Dialog did not trigger " +
176                "Window Activated event when it became visible");
177
178            dialog.closeGained.waitForFlagTriggered();
179            assertTrue(dialog.closeGained.flag(), "The first button did not gain focus " +
180                "when the dialog became visible");
181
182            assertTrue(dialog.closeButton.hasFocus(), "The first dialog button " +
183                "gained focus, but lost it afterwards");
184
185            if (parentDialog == null) {
186                frame.checkBlockedFrame(robot, modalityType + " Dialog is visible.");
187            } else {
188                parentDialog.checkBlockedDialog(robot, modalityType + " Dialog is visible.");
189            }
190
191            dialog.checkUnblockedDialog(robot, "A Frame is visible.");
192
193            dialog.openClicked.reset();
194            dialog.clickOpenButton(robot);
195            robot.waitForIdle(delay);
196
197            assertFalse(window.focusGained.flag(), "Window gained focus on becoming " +
198                "visible when Frame and Dialog are visible");
199
200            window.checkBlockedWindow(robot,
201                "The parent of the Window is blocked by " + modalityType + " Dialog.");
202
203            dummyDialog.checkBlockedDialog(robot,
204                "The parent of the Dialog is blocked by " + modalityType + " Dialog.");
205
206            childDialog.checkUnblockedDialog(robot,
207                "The parent of the Dialog is " + modalityType + " Dialog");
208
209            childWindow.checkUnblockedWindow(robot,
210                "The parent of the Window is " + modalityType + " Dialog");
211
212            childWindow.openClicked.reset();
213            childWindow.clickOpenButton(robot);
214            robot.waitForIdle(delay);
215
216            secondDialog.checkUnblockedDialog(robot,
217                "The dialog is " + modalityType + ", the parent of the dialog " +
218                "is blocked by another " + modalityType + " dialog.");
219
220            secondFrame.checkBlockedFrame(robot,
221                modalityType + " dialog is displayed immediately after showing " +
222                "this frame. Another modal dialog is alreay visible");
223
224            secondDialog.clickCloseButton(robot);
225            robot.waitForIdle(delay);
226
227            childWindow.checkUnblockedWindow(robot, "A blocking dialog was closed.");
228            robot.waitForIdle(delay);
229
230        } finally {
231            EventQueue.invokeAndWait(this::closeAll);
232        }
233    }
234
235    private void closeAll() {
236        for (Window w: allWindows) {
237            if (w != null) { w.dispose(); }
238        }
239    }
240
241
242    class CustomFrame extends TestFrame {
243
244        @Override
245        public void doOpenAction() {
246            if (dialog != null) { dialog.setVisible(true); }
247        }
248    }
249
250    class CustomDialog extends TestDialog {
251
252        public CustomDialog(Dialog dialog) {
253            super(dialog);
254        }
255
256        public CustomDialog(Frame frame) {
257            super(frame);
258        }
259
260        @Override
261        public void doOpenAction() {
262            if (window != null) { window.setVisible(true); }
263            if (dummyDialog != null) { dummyDialog.setVisible(true); }
264            if (childWindow != null) { childWindow.setVisible(true); }
265            if (childDialog != null) { childDialog.setVisible(true); }
266        }
267
268        @Override
269        public void doCloseAction() {
270            this.dispose();
271        }
272    }
273
274    class CustomWindow extends TestWindow {
275
276        public CustomWindow(Window parent) {
277            super(parent);
278        }
279
280        @Override
281        public void doOpenAction() {
282            if (secondFrame  != null) {  secondFrame.setVisible(true); }
283            if (secondDialog != null) { secondDialog.setVisible(true); }
284        }
285    }
286
287    class ParentDialog extends TestDialog {
288
289        public ParentDialog(Dialog d) { super(d); }
290
291        @Override
292        public void doOpenAction() {
293            if (dialog != null) {
294                dialog.setVisible(true);
295            }
296        }
297    }
298}
299
300