jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java
changeset 36863 bb90b1f70b42
parent 28087 622b2f420bc3
child 40128 e635645d2a8a
equal deleted inserted replaced
36862:c4d9697fee63 36863:bb90b1f70b42
     1 /*
     1 /*
     2  * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
     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.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    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
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    21  * questions.
    22  */
    22  */
    23 
    23 
    24 /*
    24 import java.awt.AWTException;
    25   test
    25 import java.awt.FlowLayout;
    26   @bug       5028014
    26 import java.awt.KeyboardFocusManager;
    27   @summary   Focus request & mouse click performed nearly synchronously shouldn't lead to a focus race.
    27 import java.awt.Point;
    28   @author    anton.tarasov@sun.com: area=awt-focus
    28 import java.awt.Robot;
    29   @run       applet MouseClickRequestFocusRaceTest.html
    29 import java.awt.event.InputEvent;
    30 */
    30 import java.awt.event.KeyEvent;
       
    31 import java.awt.event.MouseAdapter;
       
    32 import java.awt.event.MouseEvent;
    31 
    33 
    32 import java.awt.*;
    34 import javax.swing.JButton;
    33 import javax.swing.*;
    35 import javax.swing.JComponent;
    34 import java.awt.event.*;
    36 import javax.swing.JFrame;
    35 import java.applet.Applet;
    37 import javax.swing.JMenuItem;
       
    38 import javax.swing.JPopupMenu;
       
    39 import javax.swing.WindowConstants;
    36 
    40 
    37 public class MouseClickRequestFocusRaceTest extends Applet {
    41 import jdk.testlibrary.OSInfo;
    38     Robot robot;
    42 
    39     JFrame frame1 = new JFrame("Frame-1") {
    43 /**
       
    44  * @test
       
    45  * @bug 5028014
       
    46  * @summary Focus request & mouse click being performed nearly synchronously
       
    47  *          shouldn't break the focus subsystem
       
    48  * @author  anton.tarasov@sun.com: area=awt-focus
       
    49  * @library ../../../../lib/testlibrary
       
    50  * @build jdk.testlibrary.OSInfo
       
    51  * @run main MouseClickRequestFocusRaceTest
       
    52  */
       
    53 public class MouseClickRequestFocusRaceTest {
       
    54     static Robot robot;
       
    55     static JFrame frame1 = new JFrame("Frame-1") {
    40             public String toString() { return "Frame-1";}
    56             public String toString() { return "Frame-1";}
    41         };
    57         };
    42     JFrame frame2 = new JFrame("Frame-2") {
    58     static JFrame frame2 = new JFrame("Frame-2") {
    43             public String toString() { return "Frame-2";}
    59             public String toString() { return "Frame-2";}
    44         };
    60         };
    45     JButton button1 = new JButton("button-1") {
    61     static JButton button1 = new JButton("button-1") {
    46             public String toString() { return "button-1";}
    62             public String toString() { return "button-1";}
    47         };
    63         };
    48     JButton button2 = new JButton("button-2") {
    64     static JButton button2 = new JButton("button-2") {
    49             public String toString() { return "button-2";}
    65             public String toString() { return "button-2";}
    50         };
    66         };
    51     JPopupMenu popup = new JPopupMenu();
    67     static JPopupMenu popup = new JPopupMenu();
    52 
    68 
    53     public static void main(String[] args) {
    69     public static void main(String[] args) {
    54         MouseClickRequestFocusRaceTest app = new MouseClickRequestFocusRaceTest();
       
    55         app.init();
       
    56         app.start();
       
    57     }
       
    58 
       
    59     public void init() {
       
    60         try {
    70         try {
    61             robot = new Robot();
    71             robot = new Robot();
       
    72             robot.setAutoWaitForIdle(true);
       
    73             robot.setAutoDelay(100);
    62         } catch (AWTException e) {
    74         } catch (AWTException e) {
    63             throw new RuntimeException("Error: unable to create robot", e);
    75             throw new RuntimeException("Error: unable to create robot", e);
    64         }
    76         }
    65         // Create instructions for the user here, as well as set up
       
    66         // the environment -- set the layout manager, add buttons,
       
    67         // etc.
       
    68         this.setLayout (new BorderLayout ());
       
    69         Sysout.createDialogWithInstructions(new String[]
       
    70             {"Automatic test. Simply wait until it is done."
       
    71             });
       
    72     }
       
    73 
       
    74     public void start() {
       
    75         frame1.add(button1);
    77         frame1.add(button1);
    76         frame2.add(button2);
    78         frame2.add(button2);
    77         frame1.setBounds(0, 0, 200, 300);
    79         frame1.setBounds(0, 0, 200, 300);
    78         frame2.setBounds(300, 0, 200, 300);
    80         frame2.setBounds(300, 0, 200, 300);
    79         frame1.setLayout(new FlowLayout());
    81         frame1.setLayout(new FlowLayout());
   108 
   110 
   109         frame2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
   111         frame2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
   110 
   112 
   111         frame1.setVisible(true);
   113         frame1.setVisible(true);
   112         frame2.setVisible(true);
   114         frame2.setVisible(true);
   113 //        ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
   115 
   114         robot.delay(1000);
   116         robot.delay(1000);
   115 
   117         try {
   116         test();
   118             test();
       
   119         } finally {
       
   120             frame1.dispose();
       
   121             frame2.dispose();
       
   122         }
   117     }
   123     }
   118 
   124 
   119     public void test() {
   125     public static void test() {
   120         // Right click Frame-1
   126         // Right click Frame-1
   121         robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200);
   127         robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200);
   122         robot.mousePress(InputEvent.BUTTON3_MASK);
   128         robot.mousePress(InputEvent.BUTTON3_MASK);
   123         robot.delay(100);
       
   124         robot.mouseRelease(InputEvent.BUTTON3_MASK);
   129         robot.mouseRelease(InputEvent.BUTTON3_MASK);
   125 
   130 
   126 //        ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
       
   127         robot.delay(1000);
   131         robot.delay(1000);
   128 
   132 
   129         // Left click Frame-2
   133         // Left click Frame-2
   130         robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200);
   134         robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200);
   131         robot.mousePress(InputEvent.BUTTON1_MASK);
   135         robot.mousePress(InputEvent.BUTTON1_MASK);
   132         robot.delay(100);
       
   133         robot.mouseRelease(InputEvent.BUTTON1_MASK);
   136         robot.mouseRelease(InputEvent.BUTTON1_MASK);
   134 
   137 
   135 //        ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
       
   136         robot.delay(1000);
   138         robot.delay(1000);
   137 
   139 
   138         JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
   140         JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
   139         JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
   141         JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
   140 
   142 
   141         Sysout.println("focus owner: " + focusOwner);
   143         System.out.println("focus owner: " + focusOwner);
   142         Sysout.println("focused window: " + focusedWindow);
   144         System.out.println("focused window: " + focusedWindow);
   143 
   145 
   144         // Verify that the focused window is the ancestor of the focus owner
   146         // Verify that the focused window is the ancestor of the focus owner
   145         if (!focusedWindow.isAncestorOf(focusOwner)) {
   147         if (!focusedWindow.isAncestorOf(focusOwner)) {
   146             throw new TestFailedException("The focus owner is not in the focused window!");
   148             throw new RuntimeException("The focus owner is not in the focused window!");
   147         }
   149         }
   148 
   150 
   149         // Try to close native focused window
   151         if (!OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) {
   150         robot.keyPress(KeyEvent.VK_ALT);
   152             // Try to close native focused window
   151         robot.keyPress(KeyEvent.VK_F4);
   153             robot.keyPress(KeyEvent.VK_ALT);
   152         robot.keyRelease(KeyEvent.VK_F4);
   154             robot.keyPress(KeyEvent.VK_F4);
   153         robot.keyRelease(KeyEvent.VK_ALT);
   155             robot.keyRelease(KeyEvent.VK_F4);
   154 
   156             robot.keyRelease(KeyEvent.VK_ALT);
   155 //        ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
   157             robot.delay(1000);
   156         robot.delay(1000);
   158             // Verify that the Java focused window really mapped the native focused window.
   157 
   159             if (focusedWindow.isVisible()) {
   158         // Verify that the Java focused window really mapped the native focused window.
   160                 throw new RuntimeException("The focused window is different on Java and on the native level.");
   159         if (focusedWindow.isVisible()) {
   161             }
   160             throw new TestFailedException("The focused window is different on Java and on the native level.");
   162         } else {
   161         }
   163             // Try to move native focus to previous window
   162     }
   164             robot.keyPress(KeyEvent.VK_CONTROL);
   163 
   165             robot.keyPress(KeyEvent.VK_F4);
   164     class TestFailedException extends RuntimeException {
   166             robot.keyRelease(KeyEvent.VK_F4);
   165         public TestFailedException(String cause) {
   167             robot.keyRelease(KeyEvent.VK_CONTROL);
   166             super("Test failed.");
   168             robot.delay(1000);
   167             Sysout.println(cause);
   169             // Verify that the Java focused window really mapped the native focused window.
       
   170             if (focusedWindow.isFocused()) {
       
   171                 throw new RuntimeException("The focused window is different on Java and on the native level.");
       
   172             }
   168         }
   173         }
   169     }
   174     }
   170 }
   175 }
   171 
       
   172 /****************************************************
       
   173  Standard Test Machinery
       
   174  DO NOT modify anything below -- it's a standard
       
   175   chunk of code whose purpose is to make user
       
   176   interaction uniform, and thereby make it simpler
       
   177   to read and understand someone else's test.
       
   178  ****************************************************/
       
   179 
       
   180 /**
       
   181  This is part of the standard test machinery.
       
   182  It creates a dialog (with the instructions), and is the interface
       
   183   for sending text messages to the user.
       
   184  To print the instructions, send an array of strings to Sysout.createDialog
       
   185   WithInstructions method.  Put one line of instructions per array entry.
       
   186  To display a message for the tester to see, simply call Sysout.println
       
   187   with the string to be displayed.
       
   188  This mimics System.out.println but works within the test harness as well
       
   189   as standalone.
       
   190  */
       
   191 
       
   192 class Sysout
       
   193 {
       
   194     static TestDialog dialog;
       
   195 
       
   196     public static void createDialogWithInstructions( String[] instructions )
       
   197     {
       
   198         dialog = new TestDialog( new Frame(), "Instructions" );
       
   199         dialog.printInstructions( instructions );
       
   200 //        dialog.setVisible(true);
       
   201         println( "Any messages for the tester will display here." );
       
   202     }
       
   203 
       
   204     public static void createDialog( )
       
   205     {
       
   206         dialog = new TestDialog( new Frame(), "Instructions" );
       
   207         String[] defInstr = { "Instructions will appear here. ", "" } ;
       
   208         dialog.printInstructions( defInstr );
       
   209 //        dialog.setVisible(true);
       
   210         println( "Any messages for the tester will display here." );
       
   211     }
       
   212 
       
   213 
       
   214     public static void printInstructions( String[] instructions )
       
   215     {
       
   216         dialog.printInstructions( instructions );
       
   217     }
       
   218 
       
   219 
       
   220     public static void println( String messageIn )
       
   221     {
       
   222         dialog.displayMessage( messageIn );
       
   223     }
       
   224 
       
   225 }// Sysout  class
       
   226 
       
   227 /**
       
   228   This is part of the standard test machinery.  It provides a place for the
       
   229    test instructions to be displayed, and a place for interactive messages
       
   230    to the user to be displayed.
       
   231   To have the test instructions displayed, see Sysout.
       
   232   To have a message to the user be displayed, see Sysout.
       
   233   Do not call anything in this dialog directly.
       
   234   */
       
   235 class TestDialog extends Dialog
       
   236 {
       
   237 
       
   238     TextArea instructionsText;
       
   239     TextArea messageText;
       
   240     int maxStringLength = 80;
       
   241 
       
   242     //DO NOT call this directly, go through Sysout
       
   243     public TestDialog( Frame frame, String name )
       
   244     {
       
   245         super( frame, name );
       
   246         int scrollBoth = TextArea.SCROLLBARS_BOTH;
       
   247         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
       
   248         add( "North", instructionsText );
       
   249 
       
   250         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
       
   251         add("Center", messageText);
       
   252 
       
   253         pack();
       
   254 
       
   255 //        setVisible(true);
       
   256     }// TestDialog()
       
   257 
       
   258     //DO NOT call this directly, go through Sysout
       
   259     public void printInstructions( String[] instructions )
       
   260     {
       
   261         //Clear out any current instructions
       
   262         instructionsText.setText( "" );
       
   263 
       
   264         //Go down array of instruction strings
       
   265 
       
   266         String printStr, remainingStr;
       
   267         for( int i=0; i < instructions.length; i++ )
       
   268         {
       
   269             //chop up each into pieces maxSringLength long
       
   270             remainingStr = instructions[ i ];
       
   271             while( remainingStr.length() > 0 )
       
   272             {
       
   273                 //if longer than max then chop off first max chars to print
       
   274                 if( remainingStr.length() >= maxStringLength )
       
   275                 {
       
   276                     //Try to chop on a word boundary
       
   277                     int posOfSpace = remainingStr.
       
   278                         lastIndexOf( ' ', maxStringLength - 1 );
       
   279 
       
   280                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
       
   281 
       
   282                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
       
   283                     remainingStr = remainingStr.substring( posOfSpace + 1 );
       
   284                 }
       
   285                 //else just print
       
   286                 else
       
   287                 {
       
   288                     printStr = remainingStr;
       
   289                     remainingStr = "";
       
   290                 }
       
   291 
       
   292                 instructionsText.append( printStr + "\n" );
       
   293 
       
   294             }// while
       
   295 
       
   296         }// for
       
   297 
       
   298     }//printInstructions()
       
   299 
       
   300     //DO NOT call this directly, go through Sysout
       
   301     public void displayMessage( String messageIn )
       
   302     {
       
   303         messageText.append( messageIn + "\n" );
       
   304         System.out.println(messageIn);
       
   305     }
       
   306 
       
   307 }// TestDialog  class