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