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 24 /* 25 * @test 26 * @key headful 27 * @bug 8054358 28 * @summary Check correctness of modal blocking behavior for a chain of Dialogs 29 * having different modality types with a Frame as a document root. 30 * 31 * @library ../helpers ../../../../lib/testlibrary/ 32 * @build ExtendedRobot 33 * @build Flag 34 * @build TestDialog 35 * @build TestFrame 36 * @run main/timeout=500 MultipleDialogs3Test 37 */ 38 39 40 import java.awt.*; 41 import static jdk.testlibrary.Asserts.*; 42 import java.util.ArrayList; 43 import java.util.List; 44 import java.util.Collections; 45 import java.util.Iterator; 46 47 48 public class MultipleDialogs3Test { 49 50 private volatile CustomFrame frame; 51 private List<CustomDialog> dialogList; 52 private static int delay = 500; 53 54 private int dialogCount = -1; 55 56 public void createGUI() { 57 58 final int n = 8; 59 dialogList = new ArrayList<>(); 60 61 frame = new CustomFrame(); 62 frame.setLocation(50, 50); 63 frame.setVisible(true); 64 65 int x = 250; 66 int y = 50; 67 for (int i = 0; i < n; ++i) { 68 69 CustomDialog dlg; 70 if (i == 0) { 71 dlg = new CustomDialog(frame); 72 } else { 73 dlg = new CustomDialog(dialogList.get(i - 1)); 74 } 75 dlg.setLocation(x, y); 76 x += 200; 77 if (x > 600) { 78 x = 50; 79 y += 200; 80 } 81 82 Dialog.ModalityType type; 83 84 if (i % 4 == 0) { 85 type = Dialog.ModalityType.MODELESS; 86 } else if (i % 4 == 1) { 87 type = Dialog.ModalityType.DOCUMENT_MODAL; 88 } else if (i % 4 == 2) { 89 type = Dialog.ModalityType.APPLICATION_MODAL; 90 } else { 91 type = Dialog.ModalityType.TOOLKIT_MODAL; 92 } 93 94 dlg.setModalityType(type); 95 dialogList.add(dlg); 96 } 97 } 98 99 public void doTest() throws Exception { 100 101 try { 102 EventQueue.invokeAndWait(this::createGUI); 103 104 ExtendedRobot robot = new ExtendedRobot(); 105 robot.waitForIdle(delay); 106 107 frame.clickOpenButton(robot); 108 robot.waitForIdle(delay); 109 110 List<CustomDialog> dialogs = Collections.synchronizedList(dialogList); 111 final int n = dialogs.size(); 112 113 synchronized(dialogs) { 114 for (int i = 0; i < n; ++i) { 115 dialogs.get(i).activated.waitForFlagTriggered(); 116 assertTrue(dialogs.get(i).activated.flag(), i + ": Dialog did not " + 117 "trigger windowActivated event when it became visible."); 118 119 dialogs.get(i).closeGained.waitForFlagTriggered(); 120 assertTrue(dialogs.get(i).closeGained.flag(), i + ": Close button " + 121 "did not gain focus when Dialog became visible."); 122 123 assertTrue(dialogs.get(i).closeButton.hasFocus(), i + 124 ": Close button gained focus but then lost it."); 125 126 dialogs.get(i).checkUnblockedDialog(robot, 127 i + ": The dialog shouldn't be blocked."); 128 129 if (i == 0) { 130 assertTrue(dialogs.get(0).getModalityType() == 131 Dialog.ModalityType.MODELESS, "0: invalid modality type."); 132 133 frame.checkUnblockedFrame(robot, i + ": A modeless dialog was " + 134 "shown, but the parent frame became blocked."); 135 136 } else { 137 if (i % 4 == 0) { // modeless dialog 138 assertTrue(dialogs.get(i).getModalityType() == 139 Dialog.ModalityType.MODELESS, i + 140 ": incorrect dialog modality type."); 141 142 dialogs.get(i - 1).checkUnblockedDialog(robot, i + ": A modeless " + 143 "dialog was shown, but the parent dialog became blocked."); 144 145 if (i > 0) { 146 for (int j = 0; j < i - 1; ++j) { 147 148 dialogs.get(j).checkBlockedDialog(robot, i + ", " + j + 149 ": Showing a modeless dialog as a child of a " + 150 "modal dialog unblocked some dialog in its hierarchy."); 151 } 152 } 153 } else { 154 155 for (int j = 0; j < i; ++j) { 156 157 dialogs.get(j).checkBlockedDialog(robot, i + ", " + j + 158 ": A modal dialog was shown, but some dialog " + 159 "in its hierarchy became unblocked."); 160 } 161 } 162 163 frame.checkBlockedFrame(robot, i + ": A modal was dialog shown, " + 164 "but the document root frame became unblocked."); 165 } 166 167 if (i != n - 1) { 168 dialogs.get(i).clickOpenButton(robot); 169 robot.waitForIdle(delay); 170 } 171 } 172 173 for (int i = n - 1; i >= 0; --i) { 174 175 resetAll(); 176 dialogs.get(i).clickCloseButton(robot); 177 robot.waitForIdle(delay); 178 179 if (i > 0) { 180 181 dialogs.get(i - 1).activated.waitForFlagTriggered(); 182 assertTrue(dialogs.get(i - 1).activated.flag(), i + ": Dialog " + 183 "was not activated when a child dialog was closed."); 184 185 if (i == 1) { 186 187 frame.checkUnblockedFrame(robot, "1: Frame having " + 188 "a child modeless dialog was blocked."); 189 190 dialogs.get(0).checkUnblockedDialog(robot, 191 "0: A modeless dialog at the bottom " + 192 "of the hierarchy was blocked."); 193 194 } else if ((i - 1) % 4 == 0) { // dialog[i - 1] is modeless 195 196 for (int j = 0; j < i - 2; ++j) { 197 198 dialogs.get(j).checkBlockedDialog(robot, i + ", " + j + 199 ": A dialog in the hierarchy was not blocked. " + 200 "A dialog blocking a modeless dialog was closed."); 201 } 202 203 dialogs.get(i - 2).checkUnblockedDialog(robot, i + ": A modal " + 204 "dialog having a child modeless dialog was blocked."); 205 206 dialogs.get(i - 1).checkUnblockedDialog(robot, i + ": A modeless " + 207 "dialog at the bottom of the hierarchy was blocked."); 208 209 frame.checkBlockedFrame(robot, i + 210 ": Frame having a child modal dialog was not blocked."); 211 212 } else { 213 for (int j = 0; j <= i - 2; ++j) { 214 dialogs.get(j).checkBlockedDialog(robot, i + ", " + j + 215 ": A dialog in the hierarchy was not blocked. " + 216 "A child dialog was closed."); 217 } 218 219 dialogs.get(i - 1).checkUnblockedDialog(robot, (i - 1) + 220 ": A dialog was not unblocked when the modal dialog was closed."); 221 222 frame.checkBlockedFrame(robot, i + ": Frame having " + 223 "a child modal dialog was not blocked. " + 224 "Another child dialog was closed."); 225 } 226 } else { 227 frame.activated.waitForFlagTriggered(); 228 assertTrue(frame.activated.flag(), i + ": Frame was not " + 229 "activated when a child dialog was closed."); 230 } 231 } 232 } // synchronized 233 234 } finally { 235 EventQueue.invokeAndWait(this::closeAll); 236 } 237 } 238 239 private void resetAll() { 240 frame.resetStatus(); 241 Iterator<CustomDialog> it = dialogList.iterator(); 242 while (it.hasNext()) { it.next().resetStatus(); } 243 } 244 245 public void closeAll() { 246 if (frame != null) { frame.dispose(); } 247 if (dialogList != null) { 248 Iterator<CustomDialog> it = dialogList.iterator(); 249 while (it.hasNext()) { it.next().dispose(); } 250 } 251 } 252 253 class CustomFrame extends TestFrame { 254 255 @Override 256 public void doOpenAction() { 257 if ((dialogList != null) && (dialogList.size() > dialogCount)) { 258 dialogCount++; 259 CustomDialog d = dialogList.get(dialogCount); 260 if (d != null) { d.setVisible(true); } 261 } 262 } 263 } 264 265 class CustomDialog extends TestDialog { 266 267 public CustomDialog(Frame frame) { super(frame); } 268 public CustomDialog(Dialog dialog) { super(dialog); } 269 270 @Override 271 public void doCloseAction() { this.dispose(); } 272 273 @Override 274 public void doOpenAction() { 275 if ((dialogList != null) && (dialogList.size() > dialogCount)) { 276 dialogCount++; 277 CustomDialog d = dialogList.get(dialogCount); 278 if (d != null) { d.setVisible(true); } 279 } 280 } 281 } 282 283 284 public static void main(String[] args) throws Exception { 285 (new MultipleDialogs3Test()).doTest(); 286 } 287 }