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 RobotUtilities
  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.RobotUtilities;
  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 
  63     /**
  64      * Get called by test harness
  65      *
  66      * @throws Exception
  67      */
  68     public void testModelessDialogs() throws Exception {
  69         Frame frame = null;
  70         String result = "";
  71 
  72         event_checkpoint[0] = new Waypoint(); // "-Launch 1-"
  73         event_checkpoint[1] = new Waypoint(); // "-Launch 2-"
  74 
  75         // launch first frame with fistButton
  76         frame = new StartFrame();
  77         VisibilityValidator.setVisibleAndConfirm(frame);
  78         RobotUtilities.click(robot_button[0]);
  79 
  80         // Dialog must be created and onscreen before we proceed.
  81         //   The event_checkpoint waits for the Dialog to be created.
  82         //   The win_checkpoint waits for the Dialog to be visible.
  83         event_checkpoint[0].requireClear();
  84         win_checkpoint[0].requireVisible();
  85         RobotUtilities.click(robot_button[1]);
  86 
  87         // Again, the Dialog must be created and onscreen before we proceed.
  88         //   The event_checkpoint waits for the Dialog to be created.
  89         //   The win_checkpoint waits for the Dialog to be visible.
  90         event_checkpoint[1].requireClear();
  91         win_checkpoint[1].requireVisible();
  92         RobotUtilities.click(robot_text);
  93 
  94         // I'm really not sure whether the click is needed for focus
  95         // but since it's asynchronous, as is the actually gaining of focus
  96         // we might as well do our best
  97         try {
  98             EventQueue.invokeAndWait(new Runnable() {
  99                 public void run() {
 100                 }
 101             });
 102         } catch (Exception e) {
 103         }
 104 
 105         RobotUtilities.pressKey(KeyEvent.VK_SHIFT);
 106         RobotUtilities.typeKey(KeyEvent.VK_H);
 107         RobotUtilities.releaseKey(KeyEvent.VK_SHIFT);
 108         RobotUtilities.typeKey(KeyEvent.VK_E);
 109         RobotUtilities.typeKey(KeyEvent.VK_L);
 110         RobotUtilities.typeKey(KeyEvent.VK_L);
 111         RobotUtilities.typeKey(KeyEvent.VK_O);
 112 
 113         //
 114         // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE.
 115         // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT
 116         // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT
 117         //
 118         // This is a (lame) attempt at waiting for the last typeKey events to
 119         // propagate. It's not quite right because robot uses
 120         // CGRemoteOperations, which are asynchronous. But that's why I put in
 121         // the Thread.sleep
 122         try {
 123             EventQueue.invokeAndWait(new Runnable() {
 124                 public void run() {
 125                 }
 126             });
 127         } catch (Exception e) {
 128         }
 129 
 130         // Need to call this before the dialog that robot_text is in is disposed
 131         result = robot_text.getText();
 132 
 133         Thread.sleep(50); // Thread.sleep adds stability
 134         // Click Close box of modeless dialog with textField
 135         RobotUtilities.clickAt(txtDiag, 14, 10);
 136 
 137         Thread.sleep(50); // Thread.sleep adds stability
 138         // Click Close box of intermediate modal dialog
 139         RobotUtilities.clickAt(interDiag, 14, 10);
 140 
 141         Thread.sleep(50); // Thread.sleep adds stability
 142         // Click Close box of intermediate modal dialog
 143         RobotUtilities.clickAt(frame, 14, 10);
 144 
 145         String expected = "Hello";
 146     }
 147 
 148     //////////////////// Start Frame ///////////////////
 149     /**
 150      * Launches the first frame with a button in it
 151      */
 152     class StartFrame extends Frame {
 153 
 154         /**
 155          * Constructs a new instance.
 156          */
 157         public StartFrame() {
 158             super("First Frame");
 159             setLayout(new GridBagLayout());
 160             setLocation(375, 200);
 161             setSize(271, 161);
 162             Button but = new Button("Make Intermediate");
 163             but.addActionListener(new java.awt.event.ActionListener() {
 164                 public void actionPerformed(ActionEvent e) {
 165                     interDiag = new IntermediateDialog(StartFrame.this);
 166                     win_checkpoint[0] = new VisibilityValidator(interDiag);
 167                     interDiag.setSize(300, 200);
 168 
 169                     // may need listener to watch this move.
 170                     interDiag.setLocation(getLocationOnScreen());
 171                     interDiag.pack();
 172                     event_checkpoint[0].clear();
 173                     interDiag.setVisible(true);
 174                 }
 175             });
 176             Panel pan = new Panel();
 177             pan.add(but);
 178             add(pan);
 179             robot_button[0] = but;
 180             addWindowListener(new WindowAdapter() {
 181                 public void windowClosing(WindowEvent e) {
 182                     setVisible(false);
 183                     dispose();
 184                 }
 185             });
 186         }
 187     }
 188 
 189     ///////////////////////////// VARIOUS DIALOGS //////////////////////////
 190     /* A Dialog that launches a sub-dialog */
 191     class IntermediateDialog extends Dialog {
 192 
 193         Dialog m_parent;
 194 
 195         public IntermediateDialog(Frame parent) {
 196             super(parent, "Intermediate Modal", true /*Modal*/);
 197             m_parent = this;
 198             Button but = new Button("Make Text");
 199             but.addActionListener(new java.awt.event.ActionListener() {
 200                 public void actionPerformed(ActionEvent e) {
 201                     txtDiag = new TextDialog(m_parent);
 202                     win_checkpoint[1] = new VisibilityValidator(txtDiag);
 203                     txtDiag.setSize(300, 100);
 204                     event_checkpoint[1].clear();
 205                     txtDiag.setVisible(true);
 206                 }
 207             });
 208             Panel pan = new Panel();
 209             pan.add(but);
 210             add(pan);
 211             pack();
 212             addWindowListener(new WindowAdapter() {
 213                 public void windowClosing(WindowEvent e) {
 214                     setVisible(false);
 215                     dispose();
 216                 }
 217             });
 218 
 219             // The robot needs to know about us, so set global
 220             robot_button[1] = but;
 221         }
 222     }
 223 
 224     /* A Dialog that just holds a text field */
 225     class TextDialog extends Dialog {
 226 
 227         public TextDialog(Dialog parent) {
 228             super(parent, "Modeless Dialog", false /*Modeless*/);
 229             TextField txt = new TextField("", 10);
 230             Panel pan = new Panel();
 231             pan.add(txt);
 232             add(pan);
 233             pack();
 234             addWindowListener(new WindowAdapter() {
 235                 public void windowClosing(WindowEvent e) {
 236                     setVisible(false);
 237                     dispose();
 238                 }
 239             });
 240 
 241             // The robot needs to know about us, so set global
 242             robot_text = txt;
 243         }
 244     }
 245 
 246     public static void main(String[] args) throws RuntimeException {
 247         try {
 248             new NestedModelessDialogTest().testModelessDialogs();
 249         } catch (Exception e) {
 250             throw new RuntimeException("NestedModelessDialogTest object "
 251                     + "creation failed");
 252         }
 253     }
 254 }