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