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 import java.awt.*;
  26 import static jdk.testlibrary.Asserts.*;
  27 
  28 
  29 // FDF: Frame->Dialog->Frame
  30 
  31 public class ToBackFDFTest {
  32 
  33     private volatile CustomDialog dialog;
  34     private volatile TestFrame leftFrame, rightFrame;
  35 
  36     private static final int delay = 500;
  37     private final ExtendedRobot robot;
  38 
  39     private Dialog hiddenDialog;
  40     private Frame  hiddenFrame;
  41 
  42     public enum DialogOwner {HIDDEN_DIALOG, NULL_DIALOG, HIDDEN_FRAME, NULL_FRAME, FRAME};
  43 
  44     private DialogOwner owner;
  45     private volatile boolean setModal;
  46 
  47     private Dialog.ModalityType modalityType;
  48 
  49     private ToBackFDFTest(Dialog.ModalityType modType,
  50                           boolean             modal,
  51                           DialogOwner         o) throws Exception {
  52         modalityType = modType;
  53         setModal = modal;
  54         owner = o;
  55 
  56         robot = new ExtendedRobot();
  57         EventQueue.invokeLater(this::createGUI);
  58     }
  59 
  60     public ToBackFDFTest(Dialog.ModalityType modalityType,
  61                          DialogOwner         o) throws Exception {
  62         this(modalityType, false, o);
  63     }
  64 
  65     public ToBackFDFTest(boolean modal, DialogOwner o) throws Exception {
  66         this(null, modal, o);
  67     }
  68 
  69     private void createGUI() {
  70 
  71         leftFrame = new TestFrame();
  72         leftFrame.setLocation(50, 50);
  73         leftFrame.setBackground(Color.BLUE);
  74         leftFrame.setVisible(true);
  75 
  76         switch (owner) {
  77             case HIDDEN_DIALOG:
  78                 hiddenDialog = new Dialog((Frame) null);
  79                 dialog = new CustomDialog(hiddenDialog);
  80                 break;
  81             case NULL_DIALOG:
  82                 dialog = new CustomDialog((Dialog) null);
  83                 break;
  84             case HIDDEN_FRAME:
  85                 hiddenFrame = new Frame();
  86                 dialog = new CustomDialog(hiddenFrame);
  87                 break;
  88             case NULL_FRAME:
  89                 dialog = new CustomDialog((Frame) null);
  90                 break;
  91             case FRAME:
  92                 dialog = new CustomDialog(leftFrame);
  93                 break;
  94         }
  95 
  96         if (modalityType == null) {
  97             dialog.setModal(setModal);
  98             modalityType = dialog.getModalityType();
  99         } else if (modalityType != null) {
 100             dialog.setModalityType(modalityType);
 101         }
 102 
 103         dialog.setBackground(Color.WHITE);
 104         dialog.setLocation(150, 50);
 105 
 106         rightFrame = new TestFrame();
 107         rightFrame.setLocation(250, 50);
 108         rightFrame.setBackground(Color.RED);
 109 
 110         if (modalityType == Dialog.ModalityType.APPLICATION_MODAL) {
 111             rightFrame.setModalExclusionType(
 112                 Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
 113         } else if (modalityType == Dialog.ModalityType.TOOLKIT_MODAL) {
 114             rightFrame.setModalExclusionType(
 115                 Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
 116         }
 117 
 118         dialog.setVisible(true);
 119     }
 120 
 121     private void checkIfLeftOnTop(boolean refState, String msg) {
 122 
 123         Point p = leftFrame.getLocationOnScreen();
 124         int x = p.x + (int)(leftFrame.getWidth()  * 0.9);
 125         int y = p.y + (int)(leftFrame.getHeight() * 0.9);
 126         boolean f = robot.getPixelColor(x, y).equals(leftFrame.getBackground());
 127         assertEQ(refState, f, msg);
 128     }
 129 
 130     private void checkIfRightOnTop(boolean refState, String msg) {
 131 
 132         Point p = rightFrame.getLocationOnScreen();
 133         int x = p.x + (int)(rightFrame.getWidth()  * 0.1);
 134         int y = p.y + (int)(rightFrame.getHeight() * 0.9);
 135         boolean f = robot.getPixelColor(x, y).equals(rightFrame.getBackground());
 136         assertEQ(refState, f, msg);
 137     }
 138 
 139     private void Test() throws Exception {
 140 
 141         String type =
 142             dialog.getModalityType().toString().toLowerCase().replace('_', ' ');
 143 
 144         final String msg1 = "The " + type + "dialog was " +
 145             "overlapped by the blocked frame.";
 146         EventQueue.invokeAndWait(() -> { checkIfLeftOnTop(false, msg1); });
 147 
 148         EventQueue.invokeAndWait(() -> { leftFrame.toFront(); });
 149         robot.waitForIdle(delay);
 150 
 151         final String msg2 = "The dialog is still overlapped by the right frame" +
 152             " after calling toFront method for the blocked (left) frame.";
 153         EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg2); });
 154 
 155         final String msg3 = "The " + type + " dialog was overlapped by the " +
 156             "blocked frame after calling toFront method for the blocked frame.";
 157         EventQueue.invokeAndWait(() -> { checkIfLeftOnTop(false, msg3); });
 158 
 159 
 160         if (owner == DialogOwner.FRAME) { return; }
 161 
 162         EventQueue.invokeAndWait(() -> { leftFrame.toBack(); });
 163         robot.waitForIdle(delay);
 164 
 165         final String msg4 = "Calling toBack " +
 166             "for the blocked frame pushed the blocking dialog to back.";
 167         EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg4); });
 168 
 169         final String msg5 = "The " + type + " dialog was overlapped " +
 170             "by the blocked frame after toBack was called for the left frame.";
 171         EventQueue.invokeAndWait(() -> { checkIfLeftOnTop(false, msg5); });
 172     }
 173 
 174     private void docTest() throws Exception {
 175 
 176         if (owner == DialogOwner.FRAME) { Test(); }
 177         else {
 178 
 179             final String msg1 = "toBack was called for the dialog.";
 180             EventQueue.invokeAndWait(() -> {  checkIfLeftOnTop(true, msg1); });
 181             EventQueue.invokeAndWait(() -> { checkIfRightOnTop(true, msg1); });
 182 
 183             EventQueue.invokeAndWait(() -> { dialog.toFront(); });
 184             robot.waitForIdle(delay);
 185 
 186             final String msg2 = "Dialog still behind " +
 187                 "the right frame even after calling toFront method.";
 188             EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg2); });
 189             final String msg3 = "The document modal dialog " +
 190                 "gone behind the blocked left frame.";
 191             EventQueue.invokeAndWait(() -> { checkIfLeftOnTop(false, msg3); });
 192 
 193             EventQueue.invokeAndWait(() -> { leftFrame.toBack(); });
 194             robot.waitForIdle(delay);
 195 
 196             final String msg4 = "Calling toBack for the left " +
 197                 "frame pushed the document modal dialog to back.";
 198             EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg4); });
 199             final String msg5 = "The document modal dialog " +
 200                 "was pushed behind the left frame when toBack called for the frame.";
 201             EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg5); });
 202         }
 203     }
 204 
 205     private void modelessTest() throws Exception {
 206 
 207         if (owner == DialogOwner.FRAME) {
 208             final String msg = "The modeless dialog was " +
 209                 "pushed behind the parent left frame after toBack call.";
 210             EventQueue.invokeAndWait(() -> { checkIfLeftOnTop(false, msg); });
 211         } else {
 212             final String msg =
 213                 "Dialog should not overlap the frame after calling toBack.";
 214             EventQueue.invokeAndWait(() -> {  checkIfLeftOnTop(true, msg); });
 215             EventQueue.invokeAndWait(() -> { checkIfRightOnTop(true, msg); });
 216         }
 217 
 218         EventQueue.invokeAndWait(() -> { dialog.toFront(); });
 219         robot.waitForIdle(delay);
 220 
 221         final String msg1 = "The frames should not overlap the dialog " +
 222             "after calling toFront for it.";
 223         EventQueue.invokeAndWait(() -> {  checkIfLeftOnTop(false, msg1); });
 224         EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg1); });
 225 
 226         if (owner == DialogOwner.FRAME) { return; }
 227 
 228         EventQueue.invokeAndWait(() -> { leftFrame.toBack(); });
 229         robot.waitForIdle(delay);
 230 
 231         final String msg2 = "Calling toBack method for the " +
 232             "left frame pushed the modeless dialog to back.";
 233         EventQueue.invokeAndWait(() -> { checkIfRightOnTop(false, msg2); });
 234         final String msg3 = "The modeless dialog was pushed " +
 235             "behind the left frame after toBack was called for the frame.";
 236         EventQueue.invokeAndWait(() -> { checkIfLeftOnTop(false, msg3); });
 237     }
 238 
 239     public void doTest() throws Exception {
 240 
 241         try {
 242             robot.waitForIdle(delay);
 243 
 244             dialog.clickOpenButton(robot);
 245             robot.waitForIdle(delay);
 246 
 247             dialog.clickCloseButton(robot);
 248             robot.waitForIdle(delay);
 249 
 250             EventQueue.invokeAndWait(() -> { dialog.toBack(); });
 251             robot.waitForIdle(delay);
 252 
 253             switch (modalityType) {
 254                 case APPLICATION_MODAL:
 255                 case TOOLKIT_MODAL:
 256                     Test();
 257                     break;
 258                 case DOCUMENT_MODAL:
 259                     docTest();
 260                     break;
 261                 case MODELESS:
 262                     modelessTest();
 263                     break;
 264             }
 265         } finally {
 266             EventQueue.invokeAndWait(this::closeAll);
 267         }
 268     }
 269 
 270     private void closeAll() {
 271         if (dialog       != null) {       dialog.dispose(); }
 272         if (leftFrame    != null) {    leftFrame.dispose(); }
 273         if (rightFrame   != null) {   rightFrame.dispose(); }
 274         if (hiddenDialog != null) { hiddenDialog.dispose(); }
 275         if (hiddenFrame  != null) {  hiddenFrame.dispose(); }
 276     }
 277 
 278 
 279     class CustomDialog extends TestDialog {
 280 
 281         public CustomDialog(Dialog d) { super(d); }
 282         public CustomDialog(Frame  f) { super(f); }
 283 
 284         @Override
 285         public void doOpenAction() {
 286             if (rightFrame != null) {
 287                 rightFrame.setVisible(true);
 288             }
 289         }
 290     }
 291 }