1 /*
   2  * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25   @test %W% %E%
  26   @bug 6637655
  27   @summary Tests whether a LW combobox correctly overlaps a HW button
  28   @author anthony.petrov@...: area=awt.mixing
  29   @library ../regtesthelpers
  30   @build Util
  31   @run main LWComboBox
  32 */
  33 
  34 
  35 /**
  36  * LWComboBox.java
  37  *
  38  * summary:  Tests whether a LW combobox correctly overlaps a HW button
  39  */
  40 
  41 import java.awt.*;
  42 import java.awt.event.*;
  43 import javax.swing.*;
  44 import java.util.Vector;
  45 import test.java.awt.regtesthelpers.Util;
  46 
  47 
  48 
  49 public class LWComboBox
  50 {
  51     static volatile boolean failed = false;
  52 
  53     private static void init()
  54     {
  55         //*** Create instructions for the user here ***
  56 
  57         String[] instructions =
  58         {
  59             "This is an AUTOMATIC test, simply wait until it is done.",
  60             "The result (passed or failed) will be shown in the",
  61             "message window below."
  62         };
  63         Sysout.createDialog( );
  64         Sysout.printInstructions( instructions );
  65 
  66         JFrame f = new JFrame("LW menu test");
  67 
  68         JComboBox ch;
  69         Button b;
  70 
  71         Vector v = new Vector();
  72         for(int i = 1 ; i <=20;i++){
  73             v.add("Item # "+i);
  74         }
  75         ch = new JComboBox(v);
  76 
  77 
  78         b = new Button("AWT Button");
  79         b.addActionListener(new ActionListener() {
  80             public void actionPerformed(ActionEvent e) {
  81                 failed = true;
  82             }
  83         });
  84 
  85         f.add(ch,BorderLayout.NORTH);
  86         f.add(b,BorderLayout.CENTER);
  87         f.setSize(300,300);
  88         f.setVisible(true);
  89 
  90         Robot robot = Util.createRobot();
  91         robot.setAutoDelay(20);
  92 
  93         Util.waitForIdle(robot);
  94 
  95         // Pop up the combobox
  96         Point lLoc = ch.getLocationOnScreen();
  97         System.err.println("lLoc: " + lLoc);
  98         robot.mouseMove(lLoc.x + 5, lLoc.y + 5);
  99 
 100         robot.mousePress(InputEvent.BUTTON1_MASK);
 101         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 102         Util.waitForIdle(robot);
 103 
 104         // Click on the combo popup.
 105         //    It's assumed that the popup item is located
 106         //    above the heavyweight button.
 107         Point bLoc = b.getLocationOnScreen();
 108         System.err.println("bLoc: " + bLoc);
 109         robot.mouseMove(bLoc.x + 10, bLoc.y + 10);
 110 
 111         robot.mousePress(InputEvent.BUTTON1_MASK);
 112         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 113         Util.waitForIdle(robot);
 114 
 115         if (failed) {
 116             fail("The LW popup did not received the click.");
 117         } else {
 118             pass();
 119         }
 120     }//End  init()
 121 
 122 
 123 
 124     /*****************************************************
 125      * Standard Test Machinery Section
 126      * DO NOT modify anything in this section -- it's a
 127      * standard chunk of code which has all of the
 128      * synchronisation necessary for the test harness.
 129      * By keeping it the same in all tests, it is easier
 130      * to read and understand someone else's test, as
 131      * well as insuring that all tests behave correctly
 132      * with the test harness.
 133      * There is a section following this for test-
 134      * classes
 135      ******************************************************/
 136     private static boolean theTestPassed = false;
 137     private static boolean testGeneratedInterrupt = false;
 138     private static String failureMessage = "";
 139 
 140     private static Thread mainThread = null;
 141 
 142     private static int sleepTime = 300000;
 143 
 144     // Not sure about what happens if multiple of this test are
 145     //  instantiated in the same VM.  Being static (and using
 146     //  static vars), it aint gonna work.  Not worrying about
 147     //  it for now.
 148     public static void main( String args[] ) throws InterruptedException
 149     {
 150         mainThread = Thread.currentThread();
 151         try
 152         {
 153             init();
 154         }
 155         catch( TestPassedException e )
 156         {
 157             //The test passed, so just return from main and harness will
 158             // interepret this return as a pass
 159             return;
 160         }
 161         //At this point, neither test pass nor test fail has been
 162         // called -- either would have thrown an exception and ended the
 163         // test, so we know we have multiple threads.
 164 
 165         //Test involves other threads, so sleep and wait for them to
 166         // called pass() or fail()
 167         try
 168         {
 169             Thread.sleep( sleepTime );
 170             //Timed out, so fail the test
 171             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 172         }
 173         catch (InterruptedException e)
 174         {
 175             //The test harness may have interrupted the test.  If so, rethrow the exception
 176             // so that the harness gets it and deals with it.
 177             if( ! testGeneratedInterrupt ) throw e;
 178 
 179             //reset flag in case hit this code more than once for some reason (just safety)
 180             testGeneratedInterrupt = false;
 181 
 182             if ( theTestPassed == false )
 183             {
 184                 throw new RuntimeException( failureMessage );
 185             }
 186         }
 187 
 188     }//main
 189 
 190     public static synchronized void setTimeoutTo( int seconds )
 191     {
 192         sleepTime = seconds * 1000;
 193     }
 194 
 195     public static synchronized void pass()
 196     {
 197         Sysout.println( "The test passed." );
 198         Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
 199         //first check if this is executing in main thread
 200         if ( mainThread == Thread.currentThread() )
 201         {
 202             //Still in the main thread, so set the flag just for kicks,
 203             // and throw a test passed exception which will be caught
 204             // and end the test.
 205             theTestPassed = true;
 206             throw new TestPassedException();
 207         }
 208         theTestPassed = true;
 209         testGeneratedInterrupt = true;
 210         mainThread.interrupt();
 211     }//pass()
 212 
 213     public static synchronized void fail()
 214     {
 215         //test writer didn't specify why test failed, so give generic
 216         fail( "it just plain failed! :-)" );
 217     }
 218 
 219     public static synchronized void fail( String whyFailed )
 220     {
 221         Sysout.println( "The test failed: " + whyFailed );
 222         Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
 223         //check if this called from main thread
 224         if ( mainThread == Thread.currentThread() )
 225         {
 226             //If main thread, fail now 'cause not sleeping
 227             throw new RuntimeException( whyFailed );
 228         }
 229         theTestPassed = false;
 230         testGeneratedInterrupt = true;
 231         failureMessage = whyFailed;
 232         mainThread.interrupt();
 233     }//fail()
 234 
 235 }// class LWComboBox
 236 
 237 //This exception is used to exit from any level of call nesting
 238 // when it's determined that the test has passed, and immediately
 239 // end the test.
 240 class TestPassedException extends RuntimeException
 241 {
 242 }
 243 
 244 //*********** End Standard Test Machinery Section **********
 245 
 246 
 247 //************ Begin classes defined for the test ****************
 248 
 249 // if want to make listeners, here is the recommended place for them, then instantiate
 250 //  them in init()
 251 
 252 /* Example of a class which may be written as part of a test
 253 class NewClass implements anInterface
 254  {
 255    static int newVar = 0;
 256 
 257    public void eventDispatched(AWTEvent e)
 258     {
 259       //Counting events to see if we get enough
 260       eventCount++;
 261 
 262       if( eventCount == 20 )
 263        {
 264          //got enough events, so pass
 265 
 266          LWComboBox.pass();
 267        }
 268       else if( tries == 20 )
 269        {
 270          //tried too many times without getting enough events so fail
 271 
 272          LWComboBox.fail();
 273        }
 274 
 275     }// eventDispatched()
 276 
 277  }// NewClass class
 278 
 279 */
 280 
 281 
 282 //************** End classes defined for the test *******************
 283 
 284 
 285 
 286 
 287 /****************************************************
 288  Standard Test Machinery
 289  DO NOT modify anything below -- it's a standard
 290   chunk of code whose purpose is to make user
 291   interaction uniform, and thereby make it simpler
 292   to read and understand someone else's test.
 293  ****************************************************/
 294 
 295 /**
 296  This is part of the standard test machinery.
 297  It creates a dialog (with the instructions), and is the interface
 298   for sending text messages to the user.
 299  To print the instructions, send an array of strings to Sysout.createDialog
 300   WithInstructions method.  Put one line of instructions per array entry.
 301  To display a message for the tester to see, simply call Sysout.println
 302   with the string to be displayed.
 303  This mimics System.out.println but works within the test harness as well
 304   as standalone.
 305  */
 306 
 307 class Sysout
 308 {
 309     private static TestDialog dialog;
 310 
 311     public static void createDialogWithInstructions( String[] instructions )
 312     {
 313         dialog = new TestDialog( new Frame(), "Instructions" );
 314         dialog.printInstructions( instructions );
 315         dialog.setVisible(true);
 316         println( "Any messages for the tester will display here." );
 317     }
 318 
 319     public static void createDialog( )
 320     {
 321         dialog = new TestDialog( new Frame(), "Instructions" );
 322         String[] defInstr = { "Instructions will appear here. ", "" } ;
 323         dialog.printInstructions( defInstr );
 324         dialog.setVisible(true);
 325         println( "Any messages for the tester will display here." );
 326     }
 327 
 328 
 329     public static void printInstructions( String[] instructions )
 330     {
 331         dialog.printInstructions( instructions );
 332     }
 333 
 334 
 335     public static void println( String messageIn )
 336     {
 337         dialog.displayMessage( messageIn );
 338         System.out.println(messageIn);
 339     }
 340 
 341 }// Sysout  class
 342 
 343 /**
 344   This is part of the standard test machinery.  It provides a place for the
 345    test instructions to be displayed, and a place for interactive messages
 346    to the user to be displayed.
 347   To have the test instructions displayed, see Sysout.
 348   To have a message to the user be displayed, see Sysout.
 349   Do not call anything in this dialog directly.
 350   */
 351 class TestDialog extends Dialog
 352 {
 353 
 354     TextArea instructionsText;
 355     TextArea messageText;
 356     int maxStringLength = 80;
 357 
 358     //DO NOT call this directly, go through Sysout
 359     public TestDialog( Frame frame, String name )
 360     {
 361         super( frame, name );
 362         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 363         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 364         add( "North", instructionsText );
 365 
 366         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 367         add("Center", messageText);
 368 
 369         pack();
 370 
 371         setVisible(true);
 372     }// TestDialog()
 373 
 374     //DO NOT call this directly, go through Sysout
 375     public void printInstructions( String[] instructions )
 376     {
 377         //Clear out any current instructions
 378         instructionsText.setText( "" );
 379 
 380         //Go down array of instruction strings
 381 
 382         String printStr, remainingStr;
 383         for( int i=0; i < instructions.length; i++ )
 384         {
 385             //chop up each into pieces maxSringLength long
 386             remainingStr = instructions[ i ];
 387             while( remainingStr.length() > 0 )
 388             {
 389                 //if longer than max then chop off first max chars to print
 390                 if( remainingStr.length() >= maxStringLength )
 391                 {
 392                     //Try to chop on a word boundary
 393                     int posOfSpace = remainingStr.
 394                         lastIndexOf( ' ', maxStringLength - 1 );
 395 
 396                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 397 
 398                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
 399                     remainingStr = remainingStr.substring( posOfSpace + 1 );
 400                 }
 401                 //else just print
 402                 else
 403                 {
 404                     printStr = remainingStr;
 405                     remainingStr = "";
 406                 }
 407 
 408                 instructionsText.append( printStr + "\n" );
 409 
 410             }// while
 411 
 412         }// for
 413 
 414     }//printInstructions()
 415 
 416     //DO NOT call this directly, go through Sysout
 417     public void displayMessage( String messageIn )
 418     {
 419         messageText.append( messageIn + "\n" );
 420         System.out.println(messageIn);
 421     }
 422 
 423 }// TestDialog  class