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