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