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