1 /*
   2  * Copyright (c) 2005, 2015, 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       6253913
  27   @summary   Tests that a Window shown before its owner is focusable.
  28   @author    anton.tarasov@sun.com: area=awt-focus
  29   @run       applet WindowUpdateFocusabilityTest.html
  30 */
  31 
  32 import java.awt.*;
  33 import java.awt.event.*;
  34 import java.applet.Applet;
  35 import java.lang.reflect.*;
  36 
  37 public class WindowUpdateFocusabilityTest extends Applet {
  38     Robot robot;
  39     boolean focusGained = false;
  40     final Object monitor = new Object();
  41     FocusListener listener = new FocusAdapter () {
  42             public void focusGained(FocusEvent e) {
  43                 Sysout.println(e.toString());
  44                 synchronized (monitor) {
  45                     focusGained = true;
  46                     monitor.notifyAll();
  47                 }
  48             }
  49         };
  50 
  51     public static void main(String[] args) {
  52         WindowUpdateFocusabilityTest app = new WindowUpdateFocusabilityTest();
  53         app.init();
  54         app.start();
  55     }
  56 
  57     public void init() {
  58         try {
  59             robot = new Robot();
  60         } catch (AWTException e) {
  61             throw new RuntimeException("Error: couldn't create robot");
  62         }
  63         // Create instructions for the user here, as well as set up
  64         // the environment -- set the layout manager, add buttons,
  65         // etc.
  66         this.setLayout (new BorderLayout ());
  67         Sysout.createDialogWithInstructions(new String[]
  68             {"This is an automatic test. Simply wait until it's done."});
  69     }
  70 
  71     public void start() {
  72         if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
  73             Sysout.println("No testing on Motif.");
  74             return;
  75         }
  76 
  77         test(new Frame("Frame owner"));
  78         Frame dialog_owner = new Frame("dialog's owner");
  79         test(new Dialog(dialog_owner));
  80         test(new Dialog(dialog_owner, Dialog.ModalityType.DOCUMENT_MODAL));
  81         test(new Dialog(dialog_owner, Dialog.ModalityType.APPLICATION_MODAL));
  82         test(new Dialog(dialog_owner, Dialog.ModalityType.TOOLKIT_MODAL));
  83         test(new Dialog((Window) null, Dialog.ModalityType.MODELESS));
  84         test(new Dialog((Window) null, Dialog.ModalityType.DOCUMENT_MODAL));
  85         test(new Dialog((Window) null, Dialog.ModalityType.APPLICATION_MODAL));
  86         test(new Dialog((Window) null, Dialog.ModalityType.TOOLKIT_MODAL));
  87         dialog_owner.dispose();
  88     }
  89 
  90     private void test(final Window owner)
  91     {
  92         Window window0 = new Window(owner); // will not be shown
  93         Window window1 = new Window(window0);
  94         Window window2 = new Window(window1);
  95         Button button1 = new Button("button1");
  96         Button button2 = new Button("button2");
  97         button1.addFocusListener(listener);
  98         button2.addFocusListener(listener);
  99 
 100         owner.setBounds(800, 0, 100, 100);
 101         window1.setBounds(800, 300, 100, 100);
 102         window2.setBounds(800, 150, 100, 100);
 103 
 104         window1.add(button1);
 105         window2.add(button2);
 106 
 107         window2.setVisible(true);
 108         window1.setVisible(true);
 109         EventQueue.invokeLater(new Runnable() {
 110                 public void run() {
 111                     owner.setVisible(true);
 112                 }
 113             });
 114 
 115         try {
 116             EventQueue.invokeAndWait(new Runnable() {
 117                     public void run() {
 118                         // do nothing just wait until previous invokeLater will be executed
 119                     }
 120                 });
 121         } catch (InterruptedException ie) {
 122             throw new RuntimeException(ie);
 123         } catch (InvocationTargetException ite) {
 124             throw new RuntimeException(ite);
 125         }
 126 
 127         robot.delay(1000);
 128 
 129         clickOn(button1);
 130 
 131         if (!isFocusGained()) {
 132             throw new RuntimeException("Test failed: window1 is not focusable!");
 133         }
 134 
 135         focusGained = false;
 136         clickOn(button2);
 137 
 138         if (!isFocusGained()) {
 139             throw new RuntimeException("Test failed: window2 is not focusable!");
 140         }
 141 
 142         Sysout.println("Test for " + owner.getName() + " passed.");
 143         owner.dispose();
 144     }
 145 
 146     void clickOn(Component c) {
 147         Point p = c.getLocationOnScreen();
 148         Dimension d = c.getSize();
 149 
 150         Sysout.println("Clicking " + c);
 151 
 152         robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2));
 153 
 154         robot.mousePress(InputEvent.BUTTON1_MASK);
 155         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 156         waitForIdle();
 157     }
 158 
 159     void waitForIdle() {
 160         try {
 161             robot.waitForIdle();
 162             robot.delay(50);
 163             EventQueue.invokeAndWait( new Runnable() {
 164                     public void run() {} // Dummy implementation
 165                 });
 166         } catch(InterruptedException ie) {
 167             Sysout.println("waitForIdle, non-fatal exception caught:");
 168             ie.printStackTrace();
 169         } catch(InvocationTargetException ite) {
 170             Sysout.println("waitForIdle, non-fatal exception caught:");
 171             ite.printStackTrace();
 172         }
 173     }
 174 
 175     boolean isFocusGained() {
 176         synchronized (monitor) {
 177             if (!focusGained) {
 178                 try {
 179                     monitor.wait(3000);
 180                 } catch (InterruptedException e) {
 181                     Sysout.println("Interrupted unexpectedly!");
 182                     throw new RuntimeException(e);
 183                 }
 184             }
 185         }
 186         return focusGained;
 187     }
 188 }
 189 
 190 /****************************************************
 191  Standard Test Machinery
 192  DO NOT modify anything below -- it's a standard
 193   chunk of code whose purpose is to make user
 194   interaction uniform, and thereby make it simpler
 195   to read and understand someone else's test.
 196  ****************************************************/
 197 
 198 /**
 199  This is part of the standard test machinery.
 200  It creates a dialog (with the instructions), and is the interface
 201   for sending text messages to the user.
 202  To print the instructions, send an array of strings to Sysout.createDialog
 203   WithInstructions method.  Put one line of instructions per array entry.
 204  To display a message for the tester to see, simply call Sysout.println
 205   with the string to be displayed.
 206  This mimics System.out.println but works within the test harness as well
 207   as standalone.
 208  */
 209 
 210 class Sysout
 211 {
 212     static TestDialog dialog;
 213 
 214     public static void createDialogWithInstructions( String[] instructions )
 215     {
 216         dialog = new TestDialog( new Frame(), "Instructions" );
 217         dialog.printInstructions( instructions );
 218         dialog.setVisible(true);
 219         println( "Any messages for the tester will display here." );
 220     }
 221 
 222     public static void createDialog( )
 223     {
 224         dialog = new TestDialog( new Frame(), "Instructions" );
 225         String[] defInstr = { "Instructions will appear here. ", "" } ;
 226         dialog.printInstructions( defInstr );
 227         dialog.setVisible(true);
 228         println( "Any messages for the tester will display here." );
 229     }
 230 
 231 
 232     public static void printInstructions( String[] instructions )
 233     {
 234         dialog.printInstructions( instructions );
 235     }
 236 
 237 
 238     public static void println( String messageIn )
 239     {
 240         dialog.displayMessage( messageIn );
 241     }
 242 
 243 }// Sysout  class
 244 
 245 /**
 246   This is part of the standard test machinery.  It provides a place for the
 247    test instructions to be displayed, and a place for interactive messages
 248    to the user to be displayed.
 249   To have the test instructions displayed, see Sysout.
 250   To have a message to the user be displayed, see Sysout.
 251   Do not call anything in this dialog directly.
 252   */
 253 class TestDialog extends Dialog
 254 {
 255 
 256     TextArea instructionsText;
 257     TextArea messageText;
 258     int maxStringLength = 80;
 259 
 260     //DO NOT call this directly, go through Sysout
 261     public TestDialog( Frame frame, String name )
 262     {
 263         super( frame, name );
 264         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 265         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 266         add( "North", instructionsText );
 267 
 268         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 269         add("Center", messageText);
 270 
 271         pack();
 272 
 273         setVisible(true);
 274     }// TestDialog()
 275 
 276     //DO NOT call this directly, go through Sysout
 277     public void printInstructions( String[] instructions )
 278     {
 279         //Clear out any current instructions
 280         instructionsText.setText( "" );
 281 
 282         //Go down array of instruction strings
 283 
 284         String printStr, remainingStr;
 285         for( int i=0; i < instructions.length; i++ )
 286         {
 287             //chop up each into pieces maxSringLength long
 288             remainingStr = instructions[ i ];
 289             while( remainingStr.length() > 0 )
 290             {
 291                 //if longer than max then chop off first max chars to print
 292                 if( remainingStr.length() >= maxStringLength )
 293                 {
 294                     //Try to chop on a word boundary
 295                     int posOfSpace = remainingStr.
 296                         lastIndexOf( ' ', maxStringLength - 1 );
 297 
 298                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 299 
 300                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
 301                     remainingStr = remainingStr.substring( posOfSpace + 1 );
 302                 }
 303                 //else just print
 304                 else
 305                 {
 306                     printStr = remainingStr;
 307                     remainingStr = "";
 308                 }
 309 
 310                 instructionsText.append( printStr + "\n" );
 311 
 312             }// while
 313 
 314         }// for
 315 
 316     }//printInstructions()
 317 
 318     //DO NOT call this directly, go through Sysout
 319     public void displayMessage( String messageIn )
 320     {
 321         messageText.append( messageIn + "\n" );
 322         System.out.println(messageIn);
 323     }
 324 
 325 }// TestDialog  class