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