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