/* * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowFocusListener; import java.awt.geom.Area; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.util.HashMap; /* * @test * @bug 8013450 * @summary Check if the window events (Focus and Activation) are triggered correctly * when clicked on visible and clipped areas. * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) * @library ../../../../lib/testlibrary * @build Common ExtendedRobot * @run main FocusAWTTest */ public class FocusAWTTest extends Common { ExtendedRobot robot; int dx; int dy; static final int x = 20; static final int y = 400; static volatile HashMap flags = new HashMap(); static { flags.put("backgroundWindowActivated", false); flags.put("backgroundWindowDeactivated", false); flags.put("backgroundWindowGotFocus", false); flags.put("backgroundWindowLostFocus", false); flags.put("foregroundWindowGotFocus", false); flags.put("foregroundWindowLostFocus", false); flags.put("foregroundWindowActivated", false); flags.put("foregroundWindowDeactivated", false); } public static void main(String[] ignored) throws Exception{ checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT); for (Class windowClass: WINDOWS_TO_TEST) { new FocusAWTTest(windowClass).doTest(); } } public FocusAWTTest(Class windowClass) throws Exception { super(windowClass); this.robot = new ExtendedRobot(); robot.waitForIdle(); EventQueue.invokeAndWait(() -> { dx = background.getX() - x; dy = background.getY() - y; }); robot.waitForIdle(); } @Override public void initBackgroundFrame() { background = new Frame(); background.setSize(300, 300); background.setLocation(x, y); background.setFocusable(true); background.setFocusableWindowState(true); background.addWindowFocusListener(new WindowFocusListener() { public void windowGainedFocus(WindowEvent e) { flags.put("backgroundWindowGotFocus", true); } public void windowLostFocus(WindowEvent e) { flags.put("backgroundWindowLostFocus", true); } }); background.addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { flags.put("backgroundWindowActivated", true); } public void windowDeactivated(WindowEvent e) { flags.put("backgroundWindowDeactivated", true); } }); background.add(new TextArea()); background.setVisible(true); } @Override public void initGUI() { if (windowClass.equals(Frame.class)) { window = new Frame() { public void paint(Graphics g) { g.setColor(Color.BLUE); g.fillRect(0, 0, 200, 200); } }; ((Frame) window).setUndecorated(true); } else if (windowClass.equals(Dialog.class)) { window = new Dialog(background) { public void paint(Graphics g) { g.setColor(Color.BLUE); g.fillRect(0, 0, 200, 200); } }; ((Dialog) window).setUndecorated(true); } else { window = new Window(background) { public void paint(Graphics g) { g.setColor(Color.BLUE); g.fillRect(0, 0, 200, 200); } }; window.setFocusable(true); window.setFocusableWindowState(true); } window.setPreferredSize(new Dimension(200, 200)); window.setLocation(70 + dx, 450 + dy); window.setLayout(new BorderLayout()); window.addWindowFocusListener(new WindowFocusListener() { public void windowGainedFocus(WindowEvent e) { flags.put("foregroundWindowGotFocus", true); } public void windowLostFocus(WindowEvent e) { flags.put("foregroundWindowLostFocus", true); } }); window.addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { flags.put("foregroundWindowActivated", true); } public void windowDeactivated(WindowEvent e) { flags.put("foregroundWindowDeactivated", true); } }); applyShape(); window.pack(); window.setAlwaysOnTop(true); window.setVisible(true); } public void doTest() throws Exception { super.doTest(); final Point wls = new Point(); final Dimension size = new Dimension(); EventQueue.invokeAndWait(() -> { window.requestFocus(); wls.setLocation(window.getLocationOnScreen()); window.getSize(size); }); robot.waitForIdle(); check(wls.x + size.width - 5, wls.y + 5, wls.x + size.width / 3, wls.y + size.height / 3); check(wls.x + size.width / 2, wls.y + size.height / 2, wls.x + size.width * 2 / 3, wls.y + size.height * 2 / 3); EventQueue.invokeAndWait(() -> { background.dispose(); window.dispose(); }); robot.waitForIdle(); } @Override public void applyShape() { Shape shape; Area a = new Area(new Rectangle2D.Float(0, 0, 200, 200)); GeneralPath gp; gp = new GeneralPath(); gp.moveTo(190, 0); gp.lineTo(200, 0); gp.lineTo(200, 10); gp.lineTo(10, 200); gp.lineTo(0, 200); gp.lineTo(0, 190); gp.closePath(); a.subtract(new Area(gp)); shape = a; window.setShape(shape); } private void check(int xb, int yb, int xw, int yw) throws Exception { checkClick(xb, yb, "backgroundWindowGotFocus"); checkClick(xw, yw, "foregroundWindowGotFocus"); checkClick(xb, yb, "foregroundWindowLostFocus"); checkClick(xw, yw, "backgroundWindowLostFocus"); if (window instanceof Dialog || window instanceof Frame) { checkClick(xb, yb, "backgroundWindowActivated"); checkClick(xw, yw, "foregroundWindowActivated"); checkClick(xb, yb, "foregroundWindowDeactivated"); checkClick(xw, yw, "backgroundWindowDeactivated"); } } private void checkClick(int x, int y, String flag) throws Exception { System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " to trigger."); flags.put(flag, false); robot.mouseMove(x, y); robot.click(); int i = 0; while (i < 5000 && !flags.get(flag)) { robot.waitForIdle(50); i += 50; } if (!flags.get(flag)) throw new RuntimeException(flag + " is not triggered for click on point " + x + ", " + y + " for " + windowClass + "!"); } }