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