1 /* 2 @test 3 @bug 6431076 4 @summary Mouse cursor must remain DEFAULT over scrollbar when text is typed 5 @author Andrei Dmitriev: area=TextArea 6 @run main/manual Test 7 */ 8 9 import java.awt.*; 10 import java.awt.event.*; 11 12 public class Test { 13 private static void init() { 14 Frame f = new Frame("Test for cursor"); 15 final int dim = 100; 16 String line = ""; 17 for( int i=0; i<dim; ++i ) { 18 line += "a"; 19 } 20 String text = ""; 21 for( int i=0; i<dim; ++i ) { 22 text += line; 23 if( i < dim-1 ) { 24 text += "\n"; 25 } 26 } 27 28 f.setLayout( new BorderLayout () ); 29 f.add( new TextArea( text ) ); 30 f.setSize(400, 300); 31 32 f.setVisible(true); 33 34 String[] instructions = { 35 "1. Place keyboard cursor inside TextArea.", 36 "2. Repeat steps 2.* for each of two TextArea's scrollbars.", 37 "2.1. Place mouse cursor over TextArea's scrollbar.", 38 "2.2. If mouse cursor is not DEFAULT_CURSOR (arrow), test failed.", 39 "2.3. Type any symbol into TextArea.", 40 "2.4. Type ENTER symbol into TextArea.", 41 "2.5. If mouse cursor changes to TEXT_CURSOR (beam), test failed", 42 "(if cursor disappears on Windows, it's OK).", 43 "3. Test passed.", 44 }; 45 46 Sysout.createDialogWithInstructions( instructions ); 47 } 48 49 50 51 /***************************************************** 52 * Standard Test Machinery Section 53 * DO NOT modify anything in this section -- it's a 54 * standard chunk of code which has all of the 55 * synchronisation necessary for the test harness. 56 * By keeping it the same in all tests, it is easier 57 * to read and understand someone else's test, as 58 * well as insuring that all tests behave correctly 59 * with the test harness. 60 * There is a section following this for test-defined 61 * classes 62 ******************************************************/ 63 private static boolean theTestPassed = false; 64 private static boolean testGeneratedInterrupt = false; 65 private static String failureMessage = ""; 66 67 private static Thread mainThread = null; 68 69 private static int sleepTime = 300000; 70 71 public static void main( String args[] ) throws InterruptedException 72 { 73 mainThread = Thread.currentThread(); 74 try 75 { 76 init(); 77 } 78 catch( TestPassedException e ) 79 { 80 //The test passed, so just return from main and harness will 81 // interepret this return as a pass 82 return; 83 } 84 //At this point, neither test passed nor test failed has been 85 // called -- either would have thrown an exception and ended the 86 // test, so we know we have multiple threads. 87 88 //Test involves other threads, so sleep and wait for them to 89 // called pass() or fail() 90 try 91 { 92 Thread.sleep( sleepTime ); 93 //Timed out, so fail the test 94 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 95 } 96 catch (InterruptedException e) 97 { 98 if( ! testGeneratedInterrupt ) throw e; 99 100 //reset flag in case hit this code more than once for some reason (just safety) 101 testGeneratedInterrupt = false; 102 if ( theTestPassed == false ) 103 { 104 throw new RuntimeException( failureMessage ); 105 } 106 } 107 108 }//main 109 110 public static synchronized void setTimeoutTo( int seconds ) 111 { 112 sleepTime = seconds * 1000; 113 } 114 115 public static synchronized void pass() 116 { 117 Sysout.println( "The test passed." ); 118 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 119 //first check if this is executing in main thread 120 if ( mainThread == Thread.currentThread() ) 121 { 122 //Still in the main thread, so set the flag just for kicks, 123 // and throw a test passed exception which will be caught 124 // and end the test. 125 theTestPassed = true; 126 throw new TestPassedException(); 127 } 128 //pass was called from a different thread, so set the flag and interrupt 129 // the main thead. 130 theTestPassed = true; 131 testGeneratedInterrupt = true; 132 if (mainThread != null){ 133 mainThread.interrupt(); 134 } 135 }//pass() 136 137 public static synchronized void fail() 138 { 139 //test writer didn't specify why test failed, so give generic 140 fail( "it just plain failed! :-)" ); 141 } 142 143 public static synchronized void fail( String whyFailed ) 144 { 145 Sysout.println( "The test failed: " + whyFailed ); 146 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 147 //check if this called from main thread 148 if ( mainThread == Thread.currentThread() ) 149 { 150 //If main thread, fail now 'cause not sleeping 151 throw new RuntimeException( whyFailed ); 152 } 153 theTestPassed = false; 154 testGeneratedInterrupt = true; 155 failureMessage = whyFailed; 156 mainThread.interrupt(); 157 }//fail() 158 159 }// class 160 161 //This exception is used to exit from any level of call nesting 162 // when it's determined that the test has passed, and immediately 163 // end the test. 164 class TestPassedException extends RuntimeException 165 { 166 } 167 168 //*********** End Standard Test Machinery Section ********** 169 170 171 //************ Begin classes defined for the test **************** 172 173 // make listeners in a class defined here, and instantiate them in init() 174 175 /* Example of a class which may be written as part of a test 176 class NewClass implements anInterface 177 { 178 static int newVar = 0; 179 180 public void eventDispatched(AWTEvent e) 181 { 182 //Counting events to see if we get enough 183 eventCount++; 184 185 if( eventCount == 20 ) 186 { 187 //got enough events, so pass 188 189 ManualMainTest.pass(); 190 } 191 else if( tries == 20 ) 192 { 193 //tried too many times without getting enough events so fail 194 195 ManualMainTest.fail(); 196 } 197 198 }// eventDispatched() 199 200 }// NewClass class 201 202 */ 203 204 205 //************** End classes defined for the test ******************* 206 207 208 209 210 /**************************************************** 211 Standard Test Machinery 212 DO NOT modify anything below -- it's a standard 213 chunk of code whose purpose is to make user 214 interaction uniform, and thereby make it simpler 215 to read and understand someone else's test. 216 ****************************************************/ 217 218 /** 219 This is part of the standard test machinery. 220 It creates a dialog (with the instructions), and is the interface 221 for sending text messages to the user. 222 To print the instructions, send an array of strings to Sysout.createDialog 223 WithInstructions method. Put one line of instructions per array entry. 224 To display a message for the tester to see, simply call Sysout.println 225 with the string to be displayed. 226 This mimics System.out.println but works within the test harness as well 227 as standalone. 228 */ 229 230 class Sysout 231 { 232 private static TestDialog dialog; 233 private static boolean numbering = false; 234 private static int messageNumber = 0; 235 236 public static void createDialogWithInstructions( String[] instructions ) 237 { 238 dialog = new TestDialog( new Frame(), "Instructions" ); 239 dialog.printInstructions( instructions ); 240 dialog.setVisible(true); 241 println( "Any messages for the tester will display here." ); 242 } 243 244 public static void createDialog( ) 245 { 246 dialog = new TestDialog( new Frame(), "Instructions" ); 247 String[] defInstr = { "Instructions will appear here. ", "" } ; 248 dialog.printInstructions( defInstr ); 249 dialog.setVisible(true); 250 println( "Any messages for the tester will display here." ); 251 } 252 253 254 /* Enables message counting for the tester. */ 255 public static void enableNumbering(boolean enable){ 256 numbering = enable; 257 } 258 259 public static void printInstructions( String[] instructions ) 260 { 261 dialog.printInstructions( instructions ); 262 } 263 264 265 public static void println( String messageIn ) 266 { 267 if (numbering) { 268 messageIn = "" + messageNumber + " " + messageIn; 269 messageNumber++; 270 } 271 dialog.displayMessage( messageIn ); 272 } 273 274 }// Sysout class 275 276 /** 277 This is part of the standard test machinery. It provides a place for the 278 test instructions to be displayed, and a place for interactive messages 279 to the user to be displayed. 280 To have the test instructions displayed, see Sysout. 281 To have a message to the user be displayed, see Sysout. 282 Do not call anything in this dialog directly. 283 */ 284 class TestDialog extends Dialog implements ActionListener 285 { 286 287 TextArea instructionsText; 288 TextArea messageText; 289 int maxStringLength = 80; 290 Panel buttonP = new Panel(); 291 Button passB = new Button( "pass" ); 292 Button failB = new Button( "fail" ); 293 294 //DO NOT call this directly, go through Sysout 295 public TestDialog( Frame frame, String name ) 296 { 297 super( frame, name ); 298 int scrollBoth = TextArea.SCROLLBARS_BOTH; 299 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 300 add( "North", instructionsText ); 301 302 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 303 add("Center", messageText); 304 305 passB = new Button( "pass" ); 306 passB.setActionCommand( "pass" ); 307 passB.addActionListener( this ); 308 buttonP.add( "East", passB ); 309 310 failB = new Button( "fail" ); 311 failB.setActionCommand( "fail" ); 312 failB.addActionListener( this ); 313 buttonP.add( "West", failB ); 314 315 add( "South", buttonP ); 316 pack(); 317 318 setVisible(true); 319 }// TestDialog() 320 321 //DO NOT call this directly, go through Sysout 322 public void printInstructions( String[] instructions ) 323 { 324 //Clear out any current instructions 325 instructionsText.setText( "" ); 326 327 //Go down array of instruction strings 328 329 String printStr, remainingStr; 330 for( int i=0; i < instructions.length; i++ ) 331 { 332 //chop up each into pieces maxSringLength long 333 remainingStr = instructions[ i ]; 334 while( remainingStr.length() > 0 ) 335 { 336 //if longer than max then chop off first max chars to print 337 if( remainingStr.length() >= maxStringLength ) 338 { 339 //Try to chop on a word boundary 340 int posOfSpace = remainingStr. 341 lastIndexOf( ' ', maxStringLength - 1 ); 342 343 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 344 345 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 346 remainingStr = remainingStr.substring( posOfSpace + 1 ); 347 } 348 //else just print 349 else 350 { 351 printStr = remainingStr; 352 remainingStr = ""; 353 } 354 355 instructionsText.append( printStr + "\n" ); 356 357 }// while 358 359 }// for 360 361 }//printInstructions() 362 363 //DO NOT call this directly, go through Sysout 364 public void displayMessage( String messageIn ) 365 { 366 messageText.append( messageIn + "\n" ); 367 System.out.println(messageIn); 368 } 369 370 //catch presses of the passed and failed buttons. 371 //simply call the standard pass() or fail() static methods of 372 //ManualMainTest 373 public void actionPerformed( ActionEvent e ) 374 { 375 if( e.getActionCommand() == "pass" ) 376 { 377 Test.pass(); 378 } 379 else 380 { 381 Test.fail(); 382 } 383 } 384 385 }// TestDialog class