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