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