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