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       6271849
  27   @summary   Tests that component in modal excluded Window which parent is blocked responses to mouse clicks.
  28   @author    anton.tarasov@sun.com: area=awt.focus
  29   @run       applet ModalExcludedWindowClickTest.html
  30 */
  31 
  32 import java.applet.Applet;
  33 import java.awt.*;
  34 import java.awt.event.*;
  35 import java.lang.reflect.*;
  36 
  37 public class ModalExcludedWindowClickTest extends Applet {
  38     Robot robot;
  39     Frame frame = new Frame("Frame");
  40     Window w = new Window(frame);
  41     Dialog d = new Dialog ((Dialog)null, "NullParentDialog", true);
  42     Button button = new Button("Button");
  43     boolean actionPerformed = false;
  44 
  45     public static void main (String args[]) {
  46         ModalExcludedWindowClickTest app = new ModalExcludedWindowClickTest();
  47         app.init();
  48         app.start();
  49     }
  50 
  51     public void init() {
  52         try {
  53             robot = new Robot();
  54         } catch (AWTException e) {
  55             throw new RuntimeException("Error: unable to create robot", e);
  56         }
  57         // Create instructions for the user here, as well as set up
  58         // the environment -- set the layout manager, add buttons,
  59         // etc.
  60         this.setLayout (new BorderLayout ());
  61         Sysout.createDialogWithInstructions(new String[]
  62             {"This is an AUTOMATIC test", "simply wait until it is done"});
  63     }
  64 
  65     public void start() {
  66 
  67         if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
  68             Sysout.println("No testing on MToolkit.");
  69             return;
  70         }
  71 
  72         button.addActionListener(new ActionListener() {
  73                 public void actionPerformed(ActionEvent e) {
  74                     actionPerformed = true;
  75                     Sysout.println(e.paramString());
  76                 }
  77             });
  78 
  79         EventQueue.invokeLater(new Runnable() {
  80                 public void run() {
  81                     frame.setSize(200, 200);
  82                     frame.setVisible(true);
  83 
  84                     w.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
  85                     w.add(button);
  86                     w.setSize(200, 200);
  87                     w.setLocation(230, 230);
  88                     w.setVisible(true);
  89 
  90                     d.setSize(200, 200);
  91                     d.setLocation(0, 230);
  92                     d.setVisible(true);
  93 
  94                 }
  95             });
  96 
  97         waitTillShown(d);
  98 
  99         test();
 100     }
 101 
 102     void test() {
 103         clickOn(button);
 104         waitForIdle();
 105         if (!actionPerformed) {
 106             throw new RuntimeException("Test failed!");
 107         }
 108         Sysout.println("Test passed.");
 109     }
 110 
 111     void clickOn(Component c) {
 112         Point p = c.getLocationOnScreen();
 113         Dimension d = c.getSize();
 114 
 115         Sysout.println("Clicking " + c);
 116 
 117         if (c instanceof Frame) {
 118             robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + ((Frame)c).getInsets().top/2);
 119         } else {
 120             robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2));
 121         }
 122         robot.mousePress(InputEvent.BUTTON1_MASK);
 123         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 124         waitForIdle();
 125     }
 126     void waitTillShown(Component c) {
 127         while (true) {
 128             try {
 129                 Thread.sleep(100);
 130                 c.getLocationOnScreen();
 131                 break;
 132             } catch (InterruptedException e) {
 133                 throw new RuntimeException(e);
 134             } catch (IllegalComponentStateException e) {}
 135         }
 136     }
 137     void waitForIdle() {
 138         try {
 139             robot.waitForIdle();
 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         // wait longer...
 152         robot.delay(200);
 153     }
 154 }
 155 
 156 /****************************************************
 157  Standard Test Machinery
 158  DO NOT modify anything below -- it's a standard
 159   chunk of code whose purpose is to make user
 160   interaction uniform, and thereby make it simpler
 161   to read and understand someone else's test.
 162  ****************************************************/
 163 
 164 /**
 165  This is part of the standard test machinery.
 166  It creates a dialog (with the instructions), and is the interface
 167   for sending text messages to the user.
 168  To print the instructions, send an array of strings to Sysout.createDialog
 169   WithInstructions method.  Put one line of instructions per array entry.
 170  To display a message for the tester to see, simply call Sysout.println
 171   with the string to be displayed.
 172  This mimics System.out.println but works within the test harness as well
 173   as standalone.
 174  */
 175 
 176 class Sysout
 177 {
 178     static TestDialog dialog;
 179 
 180     public static void createDialogWithInstructions( String[] instructions )
 181     {
 182         dialog = new TestDialog( new Frame(), "Instructions" );
 183         dialog.printInstructions( instructions );
 184         dialog.setVisible(true);
 185         println( "Any messages for the tester will display here." );
 186     }
 187 
 188     public static void createDialog( )
 189     {
 190         dialog = new TestDialog( new Frame(), "Instructions" );
 191         String[] defInstr = { "Instructions will appear here. ", "" } ;
 192         dialog.printInstructions( defInstr );
 193         dialog.setVisible(true);
 194         println( "Any messages for the tester will display here." );
 195     }
 196 
 197 
 198     public static void printInstructions( String[] instructions )
 199     {
 200         dialog.printInstructions( instructions );
 201     }
 202 
 203 
 204     public static void println( String messageIn )
 205     {
 206         dialog.displayMessage( messageIn );
 207     }
 208 
 209 }// Sysout  class
 210 
 211 /**
 212   This is part of the standard test machinery.  It provides a place for the
 213    test instructions to be displayed, and a place for interactive messages
 214    to the user to be displayed.
 215   To have the test instructions displayed, see Sysout.
 216   To have a message to the user be displayed, see Sysout.
 217   Do not call anything in this dialog directly.
 218   */
 219 class TestDialog extends Dialog
 220 {
 221 
 222     TextArea instructionsText;
 223     TextArea messageText;
 224     int maxStringLength = 80;
 225 
 226     //DO NOT call this directly, go through Sysout
 227     public TestDialog( Frame frame, String name )
 228     {
 229         super( frame, name );
 230         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 231         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 232         add( "North", instructionsText );
 233 
 234         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 235         add("Center", messageText);
 236 
 237         pack();
 238 
 239         setVisible(true);
 240     }// TestDialog()
 241 
 242     //DO NOT call this directly, go through Sysout
 243     public void printInstructions( String[] instructions )
 244     {
 245         //Clear out any current instructions
 246         instructionsText.setText( "" );
 247 
 248         //Go down array of instruction strings
 249 
 250         String printStr, remainingStr;
 251         for( int i=0; i < instructions.length; i++ )
 252         {
 253             //chop up each into pieces maxSringLength long
 254             remainingStr = instructions[ i ];
 255             while( remainingStr.length() > 0 )
 256             {
 257                 //if longer than max then chop off first max chars to print
 258                 if( remainingStr.length() >= maxStringLength )
 259                 {
 260                     //Try to chop on a word boundary
 261                     int posOfSpace = remainingStr.
 262                         lastIndexOf( ' ', maxStringLength - 1 );
 263 
 264                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 265 
 266                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
 267                     remainingStr = remainingStr.substring( posOfSpace + 1 );
 268                 }
 269                 //else just print
 270                 else
 271                 {
 272                     printStr = remainingStr;
 273                     remainingStr = "";
 274                 }
 275 
 276                 instructionsText.append( printStr + "\n" );
 277 
 278             }// while
 279 
 280         }// for
 281 
 282     }//printInstructions()
 283 
 284     //DO NOT call this directly, go through Sysout
 285     public void displayMessage( String messageIn )
 286     {
 287         messageText.append( messageIn + "\n" );
 288         System.out.println(messageIn);
 289     }
 290 
 291 }// TestDialog  class