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