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