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