1 /* 2 * Copyright (c) 2010, 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.*; 25 import java.awt.event.WindowAdapter; 26 import java.awt.event.WindowEvent; 27 import java.awt.event.WindowFocusListener; 28 import java.awt.geom.Area; 29 import java.awt.geom.GeneralPath; 30 import java.awt.geom.Rectangle2D; 31 import java.util.HashMap; 32 33 /* 34 * @test 35 * @key headful 36 * @bug 8013450 37 * @summary Check if the window events (Focus and Activation) are triggered correctly 38 * when clicked on visible and clipped areas. 39 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) 40 * @library ../../../../lib/testlibrary 41 * @build Common ExtendedRobot 42 * @run main FocusAWTTest 43 */ 44 45 public class FocusAWTTest extends Common { 46 47 ExtendedRobot robot; 48 int dx; 49 int dy; 50 static final int x = 20; 51 static final int y = 400; 52 53 static volatile HashMap<String, Boolean> flags = new HashMap<String, Boolean>(); 54 static { 55 flags.put("backgroundWindowActivated", false); 56 flags.put("backgroundWindowDeactivated", false); 57 flags.put("backgroundWindowGotFocus", false); 58 flags.put("backgroundWindowLostFocus", false); 59 flags.put("foregroundWindowGotFocus", false); 60 flags.put("foregroundWindowLostFocus", false); 61 flags.put("foregroundWindowActivated", false); 62 flags.put("foregroundWindowDeactivated", false); 63 } 64 65 public static void main(String[] ignored) throws Exception{ 66 if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)) 67 for (Class<Window> windowClass: WINDOWS_TO_TEST) { 68 new FocusAWTTest(windowClass).doTest(); 69 } 70 } 71 72 public FocusAWTTest(Class windowClass) throws Exception { 73 super(windowClass); 74 this.robot = new ExtendedRobot(); 75 robot.waitForIdle(); 76 EventQueue.invokeAndWait(() -> { 77 dx = background.getX() - x; 78 dy = background.getY() - y; 79 }); 80 robot.waitForIdle(); 81 } 82 83 @Override 84 public void initBackgroundFrame() { 85 background = new Frame(); 86 background.setSize(300, 300); 87 background.setLocation(x, y); 88 background.setFocusable(true); 89 background.setFocusableWindowState(true); 90 91 background.addWindowFocusListener(new WindowFocusListener() { 92 public void windowGainedFocus(WindowEvent e) { flags.put("backgroundWindowGotFocus", true); } 93 public void windowLostFocus(WindowEvent e) { flags.put("backgroundWindowLostFocus", true); } 94 }); 95 96 background.addWindowListener(new WindowAdapter() { 97 public void windowActivated(WindowEvent e) { flags.put("backgroundWindowActivated", true); } 98 public void windowDeactivated(WindowEvent e) { flags.put("backgroundWindowDeactivated", true); } 99 }); 100 background.add(new TextArea()); 101 background.setVisible(true); 102 } 103 104 @Override 105 public void initGUI() { 106 if (windowClass.equals(Frame.class)) { 107 window = new Frame() { 108 public void paint(Graphics g) { 109 g.setColor(Color.BLUE); 110 g.fillRect(0, 0, 200, 200); 111 } 112 }; 113 ((Frame) window).setUndecorated(true); 114 } else if (windowClass.equals(Dialog.class)) { 115 window = new Dialog(background) { 116 public void paint(Graphics g) { 117 g.setColor(Color.BLUE); 118 g.fillRect(0, 0, 200, 200); 119 } 120 }; 121 ((Dialog) window).setUndecorated(true); 122 } else { 123 window = new Window(background) { 124 public void paint(Graphics g) { 125 g.setColor(Color.BLUE); 126 g.fillRect(0, 0, 200, 200); 127 } 128 }; 129 window.setFocusable(true); 130 window.setFocusableWindowState(true); 131 } 132 133 window.setPreferredSize(new Dimension(200, 200)); 134 window.setLocation(70 + dx, 450 + dy); 135 window.setLayout(new BorderLayout()); 136 137 window.addWindowFocusListener(new WindowFocusListener() { 138 public void windowGainedFocus(WindowEvent e) { flags.put("foregroundWindowGotFocus", true); } 139 public void windowLostFocus(WindowEvent e) { flags.put("foregroundWindowLostFocus", true); } 140 }); 141 142 window.addWindowListener(new WindowAdapter() { 143 public void windowActivated(WindowEvent e) { flags.put("foregroundWindowActivated", true); } 144 public void windowDeactivated(WindowEvent e) { flags.put("foregroundWindowDeactivated", true); } 145 }); 146 147 applyShape(); 148 window.pack(); 149 window.setAlwaysOnTop(true); 150 window.setVisible(true); 151 } 152 153 public void doTest() throws Exception { 154 super.doTest(); 155 final Point wls = new Point(); 156 final Dimension size = new Dimension(); 157 EventQueue.invokeAndWait(() -> { 158 window.requestFocus(); 159 wls.setLocation(window.getLocationOnScreen()); 160 window.getSize(size); 161 }); 162 163 robot.waitForIdle(); 164 165 check(wls.x + size.width - 5, wls.y + 5, wls.x + size.width / 3, wls.y + size.height / 3); 166 check(wls.x + size.width / 2, wls.y + size.height / 2, wls.x + size.width * 2 / 3, wls.y + size.height * 2 / 3); 167 168 EventQueue.invokeAndWait(() -> { 169 background.dispose(); 170 window.dispose(); 171 }); 172 173 robot.waitForIdle(); 174 } 175 176 @Override 177 public void applyShape() { 178 Shape shape; 179 Area a = new Area(new Rectangle2D.Float(0, 0, 200, 200)); 180 GeneralPath gp; 181 gp = new GeneralPath(); 182 gp.moveTo(190, 0); 183 gp.lineTo(200, 0); 184 gp.lineTo(200, 10); 185 gp.lineTo(10, 200); 186 gp.lineTo(0, 200); 187 gp.lineTo(0, 190); 188 gp.closePath(); 189 a.subtract(new Area(gp)); 190 shape = a; 191 192 window.setShape(shape); 193 } 194 195 private void check(int xb, int yb, int xw, int yw) throws Exception { 196 checkClick(xb, yb, "backgroundWindowGotFocus"); 197 checkClick(xw, yw, "foregroundWindowGotFocus"); 198 checkClick(xb, yb, "foregroundWindowLostFocus"); 199 checkClick(xw, yw, "backgroundWindowLostFocus"); 200 201 if (window instanceof Dialog || window instanceof Frame) { 202 checkClick(xb, yb, "backgroundWindowActivated"); 203 checkClick(xw, yw, "foregroundWindowActivated"); 204 checkClick(xb, yb, "foregroundWindowDeactivated"); 205 checkClick(xw, yw, "backgroundWindowDeactivated"); 206 } 207 208 } 209 210 private void checkClick(int x, int y, String flag) throws Exception { 211 System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " to trigger."); 212 213 flags.put(flag, false); 214 215 robot.mouseMove(x, y); 216 robot.click(); 217 int i = 0; 218 while (i < 5000 && !flags.get(flag)) { 219 robot.waitForIdle(50); 220 i += 50; 221 } 222 223 if (!flags.get(flag)) 224 throw new RuntimeException(flag + " is not triggered for click on point " + x + ", " + y + " for " + windowClass + "!"); 225 } 226 }