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