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