SetShapeDynamicallyAndClick.java revision 14851:980da45565c8
175584Sru/* 275584Sru * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. 375584Sru * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 475584Sru * 575584Sru * This code is free software; you can redistribute it and/or modify it 675584Sru * under the terms of the GNU General Public License version 2 only, as 775584Sru * published by the Free Software Foundation. 875584Sru * 975584Sru * This code is distributed in the hope that it will be useful, but WITHOUT 1075584Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1175584Sru * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1275584Sru * version 2 for more details (a copy is included in the LICENSE file that 1375584Sru * accompanied this code). 1475584Sru * 1575584Sru * You should have received a copy of the GNU General Public License version 1675584Sru * 2 along with this work; if not, write to the Free Software Foundation, 1775584Sru * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1875584Sru * 1975584Sru * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2075584Sru * or visit www.oracle.com if you need additional information or have any 2175584Sru * questions. 2275584Sru */ 2375584Sru 2475584Sruimport java.awt.*; 2575584Sruimport java.awt.event.MouseAdapter; 2675584Sruimport java.awt.event.MouseEvent; 2775584Sruimport java.awt.geom.Area; 2875584Sruimport java.awt.geom.GeneralPath; 2975584Sruimport java.awt.geom.Rectangle2D; 3075584Sru 3175584Sru/* 32 * @test 33 * @key headful 34 * @summary Check if dynamically setting a shape works 35 * 36 * Test Description: Check if PERPIXEL_TRANSPARENT Translucency type is supported 37 * by the current platform. Proceed if it is supported. Show a window which 38 * contains some components and apply a shape for the Window when the window 39 * is visible. Shape should be applied in such a way that some components 40 * are partially clipped off. Check if the components appear only partially 41 * and events work correctly for those components - ie, events occur only on 42 * the areas which appear and do not occur on the clipped off areas. Events 43 * should be checked by clicking on the visible and clipped regions. Repeat 44 * this for Window, Dialog and Frame. 45 * Expected Result: If PERPIXEL_TRANSPARENT translucency type is supported, 46 * clicking on clipped region should deliver the event to the background (it 47 * should be 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 SetShapeDynamicallyAndClick 54 */ 55 56public class SetShapeDynamicallyAndClick 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 SetShapeDynamicallyAndClick(windowClass).doTest(); 65 } 66 67 public SetShapeDynamicallyAndClick(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 south = new Label("South"); 99 south.addMouseListener(new MouseAdapter() { 100 @Override 101 public void mouseClicked(MouseEvent e) { 102 clicked |= 1 << 3; 103 } 104 }); 105 window.add(south, BorderLayout.SOUTH); 106 107 center = new List(5); 108 center.addMouseListener(new MouseAdapter() { 109 @Override 110 public void mouseClicked(MouseEvent e) { 111 clicked |= 1 << 2; 112 } 113 }); 114 window.add(center, BorderLayout.CENTER); 115 116 north = new TextField("North"); 117 north.addMouseListener(new MouseAdapter() { 118 @Override 119 public void mouseClicked(MouseEvent e) { 120 clicked |= 1 << 1; 121 } 122 }); 123 window.add(north, BorderLayout.NORTH); 124 125 window.pack(); 126 window.setVisible(true); 127 window.toFront(); 128 129 System.out.println("Checking " + window.getClass().getName() + "..."); 130 } 131 132 @Override 133 public void doTest() throws Exception { 134 135 robot.waitForIdle(); 136 137 Point wls = window.getLocationOnScreen(); 138 Point ls; 139 int y; 140 141 EventQueue.invokeAndWait(this::applyShape); 142 143 robot.waitForIdle(); 144 145 ls = north.getLocationOnScreen(); 146 checkClick(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, 1); 147 148 ls = center.getLocationOnScreen(); 149 checkClick(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, 2); 150 151 ls = south.getLocationOnScreen(); 152 checkClick(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, 3); 153 154 ls = center.getLocationOnScreen(); 155 checkClick(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, 2); 156 157 ls = north.getLocationOnScreen(); 158 y = ls.y + north.getHeight() / 2; 159 checkClick(wls.x + 200 - (y - wls.y), y, 0); 160 161 EventQueue.invokeAndWait(window::toFront); 162 robot.waitForIdle(); 163 164 ls = center.getLocationOnScreen(); 165 y = ls.y + center.getHeight() / 2; 166 checkClick(wls.x + 200 - (y - wls.y), y, 0); 167 168 EventQueue.invokeAndWait(window::toFront); 169 robot.waitForIdle(); 170 171 ls = south.getLocationOnScreen(); 172 y = ls.y + south.getHeight() / 2; 173 checkClick(wls.x + 200 - (y - wls.y), y, 0); 174 175 EventQueue.invokeAndWait(window::dispose); 176 EventQueue.invokeAndWait(background::dispose); 177 178 robot.waitForIdle(); 179 } 180 181 @Override 182 public void applyShape() { 183 Area shape = new Area(new Rectangle2D.Float(0, 0, 200, 200)); 184 GeneralPath gp; 185 gp = new GeneralPath(); 186 gp.moveTo(190, 0); 187 gp.lineTo(200, 0); 188 gp.lineTo(200, 10); 189 gp.lineTo(10, 200); 190 gp.lineTo(0, 200); 191 gp.lineTo(0, 190); 192 gp.closePath(); 193 shape.subtract(new Area(gp)); 194 195 window.setShape(shape); 196 } 197 198 void checkClick(int x, int y, int flag) throws Exception { 199 200 System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " flag to trigger."); 201 202 clicked = 0; 203 robot.mouseMove(x, y); 204 robot.click(); 205 206 for (int i = 0; i < 100; i++) 207 if ((clicked & (1 << flag)) == 0) 208 robot.delay(50); 209 else 210 break; 211 212 if ((clicked & (1 << flag)) == 0) 213 throw new RuntimeException("FAIL: Flag " + flag + " is not triggered for point " + x + ", " + y + "!"); 214 } 215} 216