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