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