1 /* 2 * Copyright (c) 2007, 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 26 @key headful 27 @bug 6496958 28 @summary Tests that breaking the proccess of clearing LW requests doesn't break focus. 29 @author anton.tarasov@...: area=awt-focus 30 @library ../../regtesthelpers 31 @build Util 32 @run main ClearLwQueueBreakTest 33 */ 34 35 import java.awt.*; 36 import javax.swing.*; 37 import java.awt.event.*; 38 import java.applet.Applet; 39 import test.java.awt.regtesthelpers.Util; 40 import java.util.concurrent.atomic.AtomicBoolean; 41 42 public class ClearLwQueueBreakTest extends Applet { 43 JFrame f1 = new JFrame("frame"); 44 JFrame f2 = new JFrame("frame"); 45 JButton b = new JButton("button"); 46 JTextField tf1 = new JTextField(" "); 47 JTextField tf2 = new JTextField(" "); 48 JTextField tf3 = new JTextField(" "); 49 AtomicBoolean typed = new AtomicBoolean(false); 50 FocusListener listener1; 51 FocusListener listener2; 52 53 Robot robot; 54 55 public static void main(String[] args) { 56 ClearLwQueueBreakTest app = new ClearLwQueueBreakTest(); 57 app.init(); 58 app.start(); 59 } 60 61 public void init() { 62 robot = Util.createRobot(); 63 64 // Create instructions for the user here, as well as set up 65 // the environment -- set the layout manager, add buttons, 66 // etc. 67 this.setLayout (new BorderLayout ()); 68 Sysout.createDialogWithInstructions(new String[] 69 {"This is an automatic test. Simply wait until it is done." 70 }); 71 } 72 73 public void start() { 74 b.addActionListener(new ActionListener() { 75 public void actionPerformed(ActionEvent e) { 76 f2.setVisible(true); 77 } 78 }); 79 tf2.addKeyListener(new KeyAdapter() { 80 public void keyTyped(KeyEvent e) { 81 if (e.getKeyChar() == '9') { 82 synchronized (typed) { 83 typed.set(true); 84 typed.notifyAll(); 85 } 86 } 87 } 88 }); 89 tf3.addKeyListener(new KeyAdapter() { 90 public void keyTyped(KeyEvent e) { 91 if (e.getKeyChar() == '8') { 92 synchronized (typed) { 93 typed.set(true); 94 typed.notifyAll(); 95 } 96 } 97 } 98 }); 99 100 listener1 = new FocusAdapter() { 101 public void focusGained(FocusEvent e) { 102 b.requestFocus(); 103 tf1.requestFocus(); 104 tf1.setFocusable(false); 105 tf2.requestFocus(); 106 } 107 }; 108 109 listener2 = new FocusAdapter() { 110 public void focusGained(FocusEvent e) { 111 b.requestFocus(); 112 tf1.requestFocus(); 113 tf2.requestFocus(); 114 tf2.setFocusable(false); 115 } 116 }; 117 118 f1.add(b); 119 f1.add(tf1); 120 f1.add(tf2); 121 f1.add(tf3); 122 f1.setLayout(new FlowLayout()); 123 f1.pack(); 124 f1.setVisible(true); 125 Util.waitForIdle(robot); 126 127 /* 128 * Break the sequence of LW requests in the middle. 129 * Test that the last request succeeds 130 */ 131 f2.addFocusListener(listener1); 132 Sysout.println("Stage 1."); 133 test1(); 134 135 136 /* 137 * Break the last LW request. 138 * Test that focus is restored correctly. 139 */ 140 f2.removeFocusListener(listener1); 141 f2.addFocusListener(listener2); 142 Sysout.println("Stage 2."); 143 test2(); 144 145 Sysout.println("Test passed."); 146 } 147 148 void test1() { 149 Util.clickOnComp(b, robot); 150 Util.waitForIdle(robot); 151 152 if (!tf2.hasFocus()) { 153 throw new TestFailedException("target component didn't get focus!"); 154 } 155 156 robot.keyPress(KeyEvent.VK_9); 157 robot.delay(50); 158 robot.keyRelease(KeyEvent.VK_9); 159 160 synchronized (typed) { 161 if (!Util.waitForCondition(typed, 2000)) { 162 throw new TestFailedException("key char couldn't be typed!"); 163 } 164 } 165 166 Util.clickOnComp(tf3, robot); 167 Util.waitForIdle(robot); 168 169 if (!tf3.hasFocus()) { 170 throw new Error("a text field couldn't be focused."); 171 } 172 173 typed.set(false); 174 robot.keyPress(KeyEvent.VK_8); 175 robot.delay(50); 176 robot.keyRelease(KeyEvent.VK_8); 177 178 synchronized (typed) { 179 if (!Util.waitForCondition(typed, 2000)) { 180 throw new TestFailedException("key char couldn't be typed!"); 181 } 182 } 183 } 184 185 void test2() { 186 Util.clickOnComp(b, robot); 187 Util.waitForIdle(robot); 188 189 if (!b.hasFocus()) { 190 throw new TestFailedException("focus wasn't restored correctly!"); 191 } 192 } 193 } 194 195 class TestFailedException extends RuntimeException { 196 TestFailedException(String msg) { 197 super("Test failed: " + msg); 198 } 199 } 200 201 /**************************************************** 202 Standard Test Machinery 203 DO NOT modify anything below -- it's a standard 204 chunk of code whose purpose is to make user 205 interaction uniform, and thereby make it simpler 206 to read and understand someone else's test. 207 ****************************************************/ 208 209 /** 210 This is part of the standard test machinery. 211 It creates a dialog (with the instructions), and is the interface 212 for sending text messages to the user. 213 To print the instructions, send an array of strings to Sysout.createDialog 214 WithInstructions method. Put one line of instructions per array entry. 215 To display a message for the tester to see, simply call Sysout.println 216 with the string to be displayed. 217 This mimics System.out.println but works within the test harness as well 218 as standalone. 219 */ 220 221 class Sysout 222 { 223 static TestDialog dialog; 224 225 public static void createDialogWithInstructions( String[] instructions ) 226 { 227 dialog = new TestDialog( new Frame(), "Instructions" ); 228 dialog.printInstructions( instructions ); 229 // dialog.setVisible(true); 230 println( "Any messages for the tester will display here." ); 231 } 232 233 public static void createDialog( ) 234 { 235 dialog = new TestDialog( new Frame(), "Instructions" ); 236 String[] defInstr = { "Instructions will appear here. ", "" } ; 237 dialog.printInstructions( defInstr ); 238 // dialog.setVisible(true); 239 println( "Any messages for the tester will display here." ); 240 } 241 242 243 public static void printInstructions( String[] instructions ) 244 { 245 dialog.printInstructions( instructions ); 246 } 247 248 249 public static void println( String messageIn ) 250 { 251 dialog.displayMessage( messageIn ); 252 } 253 254 }// Sysout class 255 256 /** 257 This is part of the standard test machinery. It provides a place for the 258 test instructions to be displayed, and a place for interactive messages 259 to the user to be displayed. 260 To have the test instructions displayed, see Sysout. 261 To have a message to the user be displayed, see Sysout. 262 Do not call anything in this dialog directly. 263 */ 264 class TestDialog extends Dialog 265 { 266 267 TextArea instructionsText; 268 TextArea messageText; 269 int maxStringLength = 80; 270 271 //DO NOT call this directly, go through Sysout 272 public TestDialog( Frame frame, String name ) 273 { 274 super( frame, name ); 275 int scrollBoth = TextArea.SCROLLBARS_BOTH; 276 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 277 add( "North", instructionsText ); 278 279 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 280 add("Center", messageText); 281 282 pack(); 283 284 // setVisible(true); 285 }// TestDialog() 286 287 //DO NOT call this directly, go through Sysout 288 public void printInstructions( String[] instructions ) 289 { 290 //Clear out any current instructions 291 instructionsText.setText( "" ); 292 293 //Go down array of instruction strings 294 295 String printStr, remainingStr; 296 for( int i=0; i < instructions.length; i++ ) 297 { 298 //chop up each into pieces maxSringLength long 299 remainingStr = instructions[ i ]; 300 while( remainingStr.length() > 0 ) 301 { 302 //if longer than max then chop off first max chars to print 303 if( remainingStr.length() >= maxStringLength ) 304 { 305 //Try to chop on a word boundary 306 int posOfSpace = remainingStr. 307 lastIndexOf( ' ', maxStringLength - 1 ); 308 309 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 310 311 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 312 remainingStr = remainingStr.substring( posOfSpace + 1 ); 313 } 314 //else just print 315 else 316 { 317 printStr = remainingStr; 318 remainingStr = ""; 319 } 320 321 instructionsText.append( printStr + "\n" ); 322 323 }// while 324 325 }// for 326 327 }//printInstructions() 328 329 //DO NOT call this directly, go through Sysout 330 public void displayMessage( String messageIn ) 331 { 332 messageText.append( messageIn + "\n" ); 333 System.out.println(messageIn); 334 } 335 336 }// TestDialog class