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