1 /*
   2  * Copyright (c) 2011, 2017, 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 8155740
  26  * @key headful
  27  * @summary See <rdar://problem/3429130>: Events: actionPerformed() method not
  28  *              called when it is button is clicked (system load related)
  29  * @summary com.apple.junit.java.awt.Frame
  30  * @library ../../../regtesthelpers
  31  * @build VisibilityValidator
  32  * @build Util
  33  * @build Waypoint
  34  * @run main NestedModelessDialogTest -Xlog:exception
  35  */
  36 
  37 /////////////////////////////////////////////////////////////////////////////
  38 //  NestedModelessDialogTest.java
  39 // The test launches a parent frame. From this parent frame it launches a modal
  40 // dialog. From the modal dialog it launches a modeless dialog with a text
  41 // field in it and tries to write into the text field. The test succeeds if you
  42 // are successfully able to write into this Nested Modeless Dialog
  43 /////////////////////////////////////////////////////////////////////////////
  44 // classes necessary for this test
  45 import java.awt.*;
  46 import java.awt.event.*;
  47 import java.util.Enumeration;
  48 
  49 import test.java.awt.regtesthelpers.Util;
  50 import test.java.awt.regtesthelpers.VisibilityValidator;
  51 import test.java.awt.regtesthelpers.Waypoint;
  52 
  53 public class NestedModelessDialogTest {
  54 
  55     Waypoint[] event_checkpoint = new Waypoint[3];
  56     VisibilityValidator[] win_checkpoint = new VisibilityValidator[2];
  57 
  58     IntermediateDialog interDiag;
  59     TextDialog txtDiag;
  60 
  61     // Global variables so the robot thread can locate things.
  62     Button[] robot_button = new Button[2];
  63     TextField robot_text = null;
  64     static Robot _robot = null;
  65 
  66     /**
  67      * Get called by test harness
  68      *
  69      * @throws Exception
  70      */
  71     public void testModelessDialogs() throws Exception {
  72         Frame frame = null;
  73         String result = "";
  74         Robot robot = getRobot();
  75 
  76         event_checkpoint[0] = new Waypoint(); // "-Launch 1-"
  77         event_checkpoint[1] = new Waypoint(); // "-Launch 2-"
  78 
  79         // launch first frame with fistButton
  80         frame = new StartFrame();
  81         VisibilityValidator.setVisibleAndConfirm(frame);
  82         Util.clickOnComp(robot_button[0], robot);
  83 
  84         // Dialog must be created and onscreen before we proceed.
  85         //   The event_checkpoint waits for the Dialog to be created.
  86         //   The win_checkpoint waits for the Dialog to be visible.
  87         event_checkpoint[0].requireClear();
  88         win_checkpoint[0].requireVisible();
  89         Util.clickOnComp(robot_button[1], robot);
  90 
  91         // Again, the Dialog must be created and onscreen before we proceed.
  92         //   The event_checkpoint waits for the Dialog to be created.
  93         //   The win_checkpoint waits for the Dialog to be visible.
  94         event_checkpoint[1].requireClear();
  95         win_checkpoint[1].requireVisible();
  96         Util.clickOnComp(robot_text, robot);
  97 
  98         // I'm really not sure whether the click is needed for focus
  99         // but since it's asynchronous, as is the actually gaining of focus
 100         // we might as well do our best
 101         try {
 102             EventQueue.invokeAndWait(new Runnable() {
 103                 public void run() {
 104                 }
 105             });
 106         } catch (Exception e) {
 107         }
 108 
 109         robot.keyPress(KeyEvent.VK_SHIFT);
 110 
 111         robot.keyPress(KeyEvent.VK_H);
 112         robot.waitForIdle();
 113         robot.keyRelease(KeyEvent.VK_H);
 114 
 115         robot.keyRelease(KeyEvent.VK_SHIFT);
 116 
 117         robot.keyPress(KeyEvent.VK_E);
 118         robot.waitForIdle();
 119         robot.keyRelease(KeyEvent.VK_E);
 120 
 121         robot.keyPress(KeyEvent.VK_L);
 122         robot.waitForIdle();
 123         robot.keyRelease(KeyEvent.VK_L);
 124 
 125         robot.keyPress(KeyEvent.VK_L);
 126         robot.waitForIdle();
 127         robot.keyRelease(KeyEvent.VK_L);
 128 
 129         robot.keyPress(KeyEvent.VK_O);
 130         robot.waitForIdle();
 131         robot.keyRelease(KeyEvent.VK_O);
 132 
 133         //
 134         // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE.
 135         // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT
 136         // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT
 137         //
 138         // This is a (lame) attempt at waiting for the last typeKey events to
 139         // propagate. It's not quite right because robot uses
 140         // CGRemoteOperations, which are asynchronous. But that's why I put in
 141         // the Thread.sleep
 142         try {
 143             EventQueue.invokeAndWait(new Runnable() {
 144                 public void run() {
 145                 }
 146             });
 147         } catch (Exception e) {
 148         }
 149 
 150         // Need to call this before the dialog that robot_text is in is disposed
 151         result = robot_text.getText();
 152 
 153         Thread.sleep(50); // Thread.sleep adds stability
 154         // Click Close box of modeless dialog with textField
 155         Util.clickOnComp(txtDiag, robot);
 156 
 157         Thread.sleep(50); // Thread.sleep adds stability
 158         // Click Close box of intermediate modal dialog
 159         Util.clickOnComp(interDiag, robot);
 160 
 161         Thread.sleep(50); // Thread.sleep adds stability
 162         // Click Close box of intermediate modal dialog
 163         Util.clickOnComp(frame, robot);
 164 
 165         String expected = "Hello";
 166     }
 167 
 168     private static Robot getRobot() {
 169         if (_robot == null) {
 170             try {
 171                 _robot = new Robot();
 172             } catch (AWTException e) {
 173                 throw new RuntimeException("Robot creation failed");
 174             }
 175         }
 176         return _robot;
 177     }
 178 
 179     //////////////////// Start Frame ///////////////////
 180     /**
 181      * Launches the first frame with a button in it
 182      */
 183     class StartFrame extends Frame {
 184 
 185         /**
 186          * Constructs a new instance.
 187          */
 188         public StartFrame() {
 189             super("First Frame");
 190             setLayout(new GridBagLayout());
 191             setLocation(375, 200);
 192             setSize(271, 161);
 193             Button but = new Button("Make Intermediate");
 194             but.addActionListener(new java.awt.event.ActionListener() {
 195                 public void actionPerformed(ActionEvent e) {
 196                     interDiag = new IntermediateDialog(StartFrame.this);
 197                     win_checkpoint[0] = new VisibilityValidator(interDiag);
 198                     interDiag.setSize(300, 200);
 199 
 200                     // may need listener to watch this move.
 201                     interDiag.setLocation(getLocationOnScreen());
 202                     interDiag.pack();
 203                     event_checkpoint[0].clear();
 204                     interDiag.setVisible(true);
 205                 }
 206             });
 207             Panel pan = new Panel();
 208             pan.add(but);
 209             add(pan);
 210             robot_button[0] = but;
 211             addWindowListener(new WindowAdapter() {
 212                 public void windowClosing(WindowEvent e) {
 213                     setVisible(false);
 214                     dispose();
 215                 }
 216             });
 217         }
 218     }
 219 
 220     ///////////////////////////// VARIOUS DIALOGS //////////////////////////
 221     /* A Dialog that launches a sub-dialog */
 222     class IntermediateDialog extends Dialog {
 223 
 224         Dialog m_parent;
 225 
 226         public IntermediateDialog(Frame parent) {
 227             super(parent, "Intermediate Modal", true /*Modal*/);
 228             m_parent = this;
 229             Button but = new Button("Make Text");
 230             but.addActionListener(new java.awt.event.ActionListener() {
 231                 public void actionPerformed(ActionEvent e) {
 232                     txtDiag = new TextDialog(m_parent);
 233                     win_checkpoint[1] = new VisibilityValidator(txtDiag);
 234                     txtDiag.setSize(300, 100);
 235                     event_checkpoint[1].clear();
 236                     txtDiag.setVisible(true);
 237                 }
 238             });
 239             Panel pan = new Panel();
 240             pan.add(but);
 241             add(pan);
 242             pack();
 243             addWindowListener(new WindowAdapter() {
 244                 public void windowClosing(WindowEvent e) {
 245                     setVisible(false);
 246                     dispose();
 247                 }
 248             });
 249 
 250             // The robot needs to know about us, so set global
 251             robot_button[1] = but;
 252         }
 253     }
 254 
 255     /* A Dialog that just holds a text field */
 256     class TextDialog extends Dialog {
 257 
 258         public TextDialog(Dialog parent) {
 259             super(parent, "Modeless Dialog", false /*Modeless*/);
 260             TextField txt = new TextField("", 10);
 261             Panel pan = new Panel();
 262             pan.add(txt);
 263             add(pan);
 264             pack();
 265             addWindowListener(new WindowAdapter() {
 266                 public void windowClosing(WindowEvent e) {
 267                     setVisible(false);
 268                     dispose();
 269                 }
 270             });
 271 
 272             // The robot needs to know about us, so set global
 273             robot_text = txt;
 274         }
 275     }
 276 
 277     public static void main(String[] args) throws RuntimeException {
 278         try {
 279             new NestedModelessDialogTest().testModelessDialogs();
 280         } catch (Exception e) {
 281             throw new RuntimeException("NestedModelessDialogTest object "
 282                     + "creation failed");
 283         }
 284     }
 285 }