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