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