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