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