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