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 * @key headful 46 * @bug 5028014 47 * @summary Focus request & mouse click being performed nearly synchronously 48 * shouldn't break the focus subsystem 49 * @author anton.tarasov@sun.com: area=awt-focus 50 * @library ../../../../lib/testlibrary 51 * @build jdk.testlibrary.OSInfo 52 * @run main MouseClickRequestFocusRaceTest 53 */ 54 public class MouseClickRequestFocusRaceTest { 55 static Robot robot; 56 static JFrame frame1 = new JFrame("Frame-1") { 57 public String toString() { return "Frame-1";} 58 }; 59 static JFrame frame2 = new JFrame("Frame-2") { 60 public String toString() { return "Frame-2";} 61 }; 62 static JButton button1 = new JButton("button-1") { 63 public String toString() { return "button-1";} 64 }; 65 static JButton button2 = new JButton("button-2") { 66 public String toString() { return "button-2";} 67 }; 68 static JPopupMenu popup = new JPopupMenu(); 69 70 public static void main(String[] args) { 71 try { 72 robot = new Robot(); 73 robot.setAutoWaitForIdle(true); 74 robot.setAutoDelay(100); 75 } catch (AWTException e) { 76 throw new RuntimeException("Error: unable to create robot", e); 77 } 78 frame1.add(button1); 79 frame2.add(button2); 80 frame1.setBounds(0, 0, 200, 300); 81 frame2.setBounds(300, 0, 200, 300); 82 frame1.setLayout(new FlowLayout()); 83 frame2.setLayout(new FlowLayout()); 84 85 popup.add(new JMenuItem("black")); 86 popup.add(new JMenuItem("yellow")); 87 popup.add(new JMenuItem("white")); 88 89 frame1.add(popup); 90 91 frame1.addMouseListener(new MouseAdapter() { 92 void popup(MouseEvent e) { 93 if (e.isPopupTrigger()) { 94 Point loc = button1.getLocation(); 95 popup.show(button1, e.getX() - loc.x, e.getY() - loc.y); 96 } 97 } 98 public void mousePressed(MouseEvent e) { 99 popup(e); 100 } 101 public void mouseReleased(MouseEvent e) { 102 popup(e); 103 } 104 }); 105 106 frame2.addMouseListener(new MouseAdapter() { 107 public void mousePressed(MouseEvent e) { 108 button1.requestFocusInWindow(); 109 } 110 }); 111 112 frame2.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 113 114 frame1.setVisible(true); 115 frame2.setVisible(true); 116 117 robot.delay(1000); 118 try { 119 test(); 120 } finally { 121 frame1.dispose(); 122 frame2.dispose(); 123 } 124 } 125 126 public static void test() { 127 // Right click Frame-1 128 robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200); 129 robot.mousePress(InputEvent.BUTTON3_MASK); 130 robot.mouseRelease(InputEvent.BUTTON3_MASK); 131 132 robot.delay(1000); 133 134 // Left click Frame-2 135 robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200); 136 robot.mousePress(InputEvent.BUTTON1_MASK); 137 robot.mouseRelease(InputEvent.BUTTON1_MASK); 138 139 robot.delay(1000); 140 141 JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 142 JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow(); 143 144 System.out.println("focus owner: " + focusOwner); 145 System.out.println("focused window: " + focusedWindow); 146 147 // Verify that the focused window is the ancestor of the focus owner 148 if (!focusedWindow.isAncestorOf(focusOwner)) { 149 throw new RuntimeException("The focus owner is not in the focused window!"); 150 } 151 152 if (!OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) { 153 // Try to close native focused window 154 robot.keyPress(KeyEvent.VK_ALT); 155 robot.keyPress(KeyEvent.VK_F4); 156 robot.keyRelease(KeyEvent.VK_F4); 157 robot.keyRelease(KeyEvent.VK_ALT); 158 robot.delay(1000); 159 // Verify that the Java focused window really mapped the native focused window. 160 if (focusedWindow.isVisible()) { 161 throw new RuntimeException("The focused window is different on Java and on the native level."); 162 } 163 } else { 164 // Try to move native focus to previous window 165 robot.keyPress(KeyEvent.VK_CONTROL); 166 robot.keyPress(KeyEvent.VK_F4); 167 robot.keyRelease(KeyEvent.VK_F4); 168 robot.keyRelease(KeyEvent.VK_CONTROL); 169 robot.delay(1000); 170 // Verify that the Java focused window really mapped the native focused window. 171 if (focusedWindow.isFocused()) { 172 throw new RuntimeException("The focused window is different on Java and on the native level."); 173 } 174 } 175 } 176 }