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