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 import java.awt.AWTException; 25 import java.awt.FlowLayout; 26 import java.awt.KeyboardFocusManager; 27 import java.awt.Point; 28 import java.awt.Robot; 29 import java.awt.event.InputEvent; 30 import java.awt.event.KeyEvent; 31 import java.awt.event.MouseAdapter; 32 import java.awt.event.MouseEvent; 33 34 import javax.swing.JButton; 35 import javax.swing.JComponent; 36 import javax.swing.JFrame; 37 import javax.swing.JMenuItem; 38 import javax.swing.JPopupMenu; 39 import javax.swing.WindowConstants; 40 41 import jdk.testlibrary.OSInfo; 42 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") { 56 public String toString() { return "Frame-1";} 57 }; 58 static JFrame frame2 = new JFrame("Frame-2") { 59 public String toString() { return "Frame-2";} 60 }; 61 static JButton button1 = new JButton("button-1") { 62 public String toString() { return "button-1";} 63 }; 64 static JButton button2 = new JButton("button-2") { 65 public String toString() { return "button-2";} 66 }; 67 static JPopupMenu popup = new JPopupMenu(); 68 69 public static void main(String[] args) { 70 try { 71 robot = new Robot(); 72 robot.setAutoWaitForIdle(true); 73 robot.setAutoDelay(100); 74 } catch (AWTException e) { 75 throw new RuntimeException("Error: unable to create robot", e); 76 } 77 frame1.add(button1); 78 frame2.add(button2); 79 frame1.setBounds(0, 0, 200, 300); 80 frame2.setBounds(300, 0, 200, 300); 81 frame1.setLayout(new FlowLayout()); 82 frame2.setLayout(new FlowLayout()); 83 84 popup.add(new JMenuItem("black")); 85 popup.add(new JMenuItem("yellow")); 86 popup.add(new JMenuItem("white")); 87 88 frame1.add(popup); 89 90 frame1.addMouseListener(new MouseAdapter() { 91 void popup(MouseEvent e) { 92 if (e.isPopupTrigger()) { 93 Point loc = button1.getLocation(); 94 popup.show(button1, e.getX() - loc.x, e.getY() - loc.y); 95 } 96 } 97 public void mousePressed(MouseEvent e) { 98 popup(e); 99 } 100 public void mouseReleased(MouseEvent e) { 101 popup(e); 102 } 103 }); 104 105 frame2.addMouseListener(new MouseAdapter() { 106 public void mousePressed(MouseEvent e) { 107 button1.requestFocusInWindow(); 108 } 109 }); 110 111 frame2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 112 113 frame1.setVisible(true); 114 frame2.setVisible(true); 115 116 robot.delay(1000); 117 try { 118 test(); 119 } finally { 120 frame1.dispose(); 121 frame2.dispose(); 122 } 123 } 124 125 public static void test() { 126 // Right click Frame-1 127 robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200); 128 robot.mousePress(InputEvent.BUTTON3_MASK); 129 robot.mouseRelease(InputEvent.BUTTON3_MASK); 130 131 robot.delay(1000); 132 133 // Left click Frame-2 134 robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200); 135 robot.mousePress(InputEvent.BUTTON1_MASK); 136 robot.mouseRelease(InputEvent.BUTTON1_MASK); 137 138 robot.delay(1000); 139 140 JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 141 JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); 142 143 System.out.println("focus owner: " + focusOwner); 144 System.out.println("focused window: " + focusedWindow); 145 146 // Verify that the focused window is the ancestor of the focus owner 147 if (!focusedWindow.isAncestorOf(focusOwner)) { 148 throw new RuntimeException("The focus owner is not in the focused window!"); 149 } 150 151 if (!OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) { 152 // Try to close native focused window 153 robot.keyPress(KeyEvent.VK_ALT); 154 robot.keyPress(KeyEvent.VK_F4); 155 robot.keyRelease(KeyEvent.VK_F4); 156 robot.keyRelease(KeyEvent.VK_ALT); 157 robot.delay(1000); 158 // Verify that the Java focused window really mapped the native focused window. 159 if (focusedWindow.isVisible()) { 160 throw new RuntimeException("The focused window is different on Java and on the native level."); 161 } 162 } else { 163 // Try to move native focus to previous window 164 robot.keyPress(KeyEvent.VK_CONTROL); 165 robot.keyPress(KeyEvent.VK_F4); 166 robot.keyRelease(KeyEvent.VK_F4); 167 robot.keyRelease(KeyEvent.VK_CONTROL); 168 robot.delay(1000); 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 } 173 } 174 } 175 }