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 public void initBackgroundFrame() { 72 super.initBackgroundFrame(); 73 background.addMouseListener(new MouseAdapter() { 74 @Override 75 public void mouseClicked(MouseEvent e) { 76 clicked |= 1 << 0; 77 } 78 }); 79 } 80 81 public void initGUI() { 82 if (windowClass.equals(Frame.class)) { 83 window = new Frame(); 84 ((Frame) window).setUndecorated(true); 85 } else if (windowClass.equals(Dialog.class)) { 86 window = new Dialog(background); 87 ((Dialog) window).setUndecorated(true); 88 } else { 89 window = new Window(background); 90 } 91 92 window.setLocation(2 * dl, 2 * dl); 93 window.setPreferredSize(new Dimension(200, 200)); 94 window.setLayout(new BorderLayout()); 95 96 window.addComponentListener(new ComponentAdapter() { 97 public void componentResized(ComponentEvent e) { 98 applyShape(); 99 } 100 }); 101 102 south = new Label("South"); 103 south.addMouseListener(new MouseAdapter() { 104 @Override 105 public void mouseClicked(MouseEvent e) { 106 clicked |= 1 << 3; 107 } 108 }); 109 window.add(south, BorderLayout.SOUTH); 110 111 center = new List(5); 112 center.addMouseListener(new MouseAdapter() { 113 @Override 114 public void mouseClicked(MouseEvent e) { 115 clicked |= 1 << 2; 116 } 117 }); 118 window.add(center, BorderLayout.CENTER); 119 120 north = new TextField("North"); 121 north.addMouseListener(new MouseAdapter() { 122 @Override 123 public void mouseClicked(MouseEvent e) { 124 clicked |= 1 << 1; 125 } 126 }); 127 window.add(north, BorderLayout.NORTH); 128 129 window.pack(); 130 window.setVisible(true); 131 window.toFront(); 132 133 System.out.println("Checking " + window.getClass().getName() + "..."); 134 } 135 136 public void doTest() throws Exception { 137 138 robot.waitForIdle(); 139 140 Point wls = window.getLocationOnScreen(); 141 Point ls; 142 int y; 143 ls = north.getLocationOnScreen(); 144 checkClick(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, 1); 145 146 ls = center.getLocationOnScreen(); 147 checkClick(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, 2); 148 149 ls = south.getLocationOnScreen(); 150 checkClick(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, 3); 151 152 ls = center.getLocationOnScreen(); 153 checkClick(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, 2); 154 155 ls = north.getLocationOnScreen(); 156 y = ls.y + north.getHeight() / 2; 157 checkClick(wls.x + 200 - (y - wls.y), y, 0); 158 159 EventQueue.invokeAndWait(window::toFront); 160 robot.waitForIdle(); 161 162 ls = center.getLocationOnScreen(); 163 y = ls.y + center.getHeight() / 2; 164 checkClick(wls.x + 200 - (y - wls.y), y, 0); 165 166 EventQueue.invokeAndWait(window::toFront); 167 robot.waitForIdle(); 168 169 ls = south.getLocationOnScreen(); 170 y = ls.y + south.getHeight() / 2; 171 checkClick(wls.x + 200 - (y - wls.y), y, 0); 172 173 EventQueue.invokeAndWait(window::dispose); 174 EventQueue.invokeAndWait(background::dispose); 175 176 robot.waitForIdle(); 177 } 178 179 @Override 180 public void applyShape() { 181 Area shape = new Area(new Rectangle2D.Float(0, 0, 200, 200)); 182 GeneralPath gp; 183 gp = new GeneralPath(); 184 gp.moveTo(190, 0); 185 gp.lineTo(200, 0); 186 gp.lineTo(200, 10); 187 gp.lineTo(10, 200); 188 gp.lineTo(0, 200); 189 gp.lineTo(0, 190); 190 gp.closePath(); 191 shape.subtract(new Area(gp)); 192 193 window.setShape(shape); 194 } 195 196 void checkClick(int x, int y, int flag) throws Exception { 197 198 System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " flag to trigger."); 199 200 clicked = 0; 201 robot.mouseMove(x, y); 202 robot.click(); 203 204 for (int i = 0; i < 100; i++) 205 if ((clicked & (1 << flag)) == 0) 206 robot.delay(50); 207 else 208 break; 209 210 if ((clicked & (1 << flag)) == 0) 211 throw new RuntimeException("FAIL: Flag " + flag + " is not triggered for point " + x + ", " + y + "!"); 212 } 213 }