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.MouseAdapter; 26 import java.awt.event.MouseEvent; 27 import java.awt.geom.Area; 28 import java.awt.geom.GeneralPath; 29 import java.awt.geom.Rectangle2D; 30 31 /* 32 * @test 33 * @summary Check whether clicking on clipped region of dynamically set shape 34 * deliver the event to the background (it should be another Window 35 * behind the test window) 36 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) 37 * @library ../../../../lib/testlibrary 38 * @build Common ExtendedRobot 39 * @run main SetShapeDynamicallyAndClick 40 */ 41 42 public class SetShapeDynamicallyAndClick extends Common { 43 44 Component south, center, north; 45 volatile int clicked; 46 47 public static void main(String[] args) throws Exception { 48 if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)) 49 for (Class<Window> windowClass: WINDOWS_TO_TEST) 50 new SetShapeDynamicallyAndClick(windowClass).doTest(); 51 } 52 53 public SetShapeDynamicallyAndClick(Class windowClass) throws Exception { 54 super(windowClass); 55 } 56 57 public void initBackgroundFrame() { 58 super.initBackgroundFrame(); 59 background.addMouseListener(new MouseAdapter() { 60 @Override 61 public void mouseClicked(MouseEvent e) { 62 clicked |= 1 << 0; 63 } 64 }); 65 } 66 67 public void initGUI() { 68 if (windowClass.equals(Frame.class)) { 69 window = new Frame(); 70 ((Frame) window).setUndecorated(true); 71 } else if (windowClass.equals(Dialog.class)) { 72 window = new Dialog(background); 73 ((Dialog) window).setUndecorated(true); 74 } else { 75 window = new Window(background); 76 } 77 78 window.setLocation(2 * dl, 2 * dl); 79 window.setPreferredSize(new Dimension(200, 200)); 80 window.setLayout(new BorderLayout()); 81 82 south = new Label("South"); 83 south.addMouseListener(new MouseAdapter() { 84 @Override 85 public void mouseClicked(MouseEvent e) { 86 clicked |= 1 << 3; 87 } 88 }); 89 window.add(south, BorderLayout.SOUTH); 90 91 center = new List(5); 92 center.addMouseListener(new MouseAdapter() { 93 @Override 94 public void mouseClicked(MouseEvent e) { 95 clicked |= 1 << 2; 96 } 97 }); 98 window.add(center, BorderLayout.CENTER); 99 100 north = new TextField("North"); 101 north.addMouseListener(new MouseAdapter() { 102 @Override 103 public void mouseClicked(MouseEvent e) { 104 clicked |= 1 << 1; 105 } 106 }); 107 window.add(north, BorderLayout.NORTH); 108 109 window.pack(); 110 window.setVisible(true); 111 window.toFront(); 112 113 System.out.println("Checking " + window.getClass().getName() + "..."); 114 } 115 116 public void doTest() throws Exception { 117 118 robot.waitForIdle(); 119 120 Point wls = window.getLocationOnScreen(); 121 Point ls; 122 int y; 123 124 EventQueue.invokeAndWait(this::applyShape); 125 126 robot.waitForIdle(); 127 128 ls = north.getLocationOnScreen(); 129 checkClick(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, 1); 130 131 ls = center.getLocationOnScreen(); 132 checkClick(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, 2); 133 134 ls = south.getLocationOnScreen(); 135 checkClick(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, 3); 136 137 ls = center.getLocationOnScreen(); 138 checkClick(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, 2); 139 140 ls = north.getLocationOnScreen(); 141 y = ls.y + north.getHeight() / 2; 142 checkClick(wls.x + 200 - (y - wls.y), y, 0); 143 144 EventQueue.invokeAndWait(window::toFront); 145 robot.waitForIdle(); 146 147 ls = center.getLocationOnScreen(); 148 y = ls.y + center.getHeight() / 2; 149 checkClick(wls.x + 200 - (y - wls.y), y, 0); 150 151 EventQueue.invokeAndWait(window::toFront); 152 robot.waitForIdle(); 153 154 ls = south.getLocationOnScreen(); 155 y = ls.y + south.getHeight() / 2; 156 checkClick(wls.x + 200 - (y - wls.y), y, 0); 157 158 EventQueue.invokeAndWait(window::dispose); 159 EventQueue.invokeAndWait(background::dispose); 160 161 robot.waitForIdle(); 162 } 163 164 @Override 165 public void applyShape() { 166 Area shape = new Area(new Rectangle2D.Float(0, 0, 200, 200)); 167 GeneralPath gp; 168 gp = new GeneralPath(); 169 gp.moveTo(190, 0); 170 gp.lineTo(200, 0); 171 gp.lineTo(200, 10); 172 gp.lineTo(10, 200); 173 gp.lineTo(0, 200); 174 gp.lineTo(0, 190); 175 gp.closePath(); 176 shape.subtract(new Area(gp)); 177 178 window.setShape(shape); 179 } 180 181 void checkClick(int x, int y, int flag) throws Exception { 182 183 System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " flag to trigger."); 184 185 clicked = 0; 186 robot.mouseMove(x, y); 187 robot.click(); 188 189 for (int i = 0; i < 100; i++) 190 if ((clicked & (1 << flag)) == 0) 191 robot.delay(50); 192 else 193 break; 194 195 if ((clicked & (1 << flag)) == 0) 196 throw new RuntimeException("FAIL: Flag " + flag + " is not triggered for point " + x + ", " + y + "!"); 197 } 198 }