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