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