ShapedTranslucentWindowClick.java revision 14851:980da45565c8
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 24import java.awt.*; 25import java.awt.event.*; 26import java.awt.geom.Area; 27import java.awt.geom.GeneralPath; 28import java.awt.geom.Rectangle2D; 29import java.util.BitSet; 30 31/* 32 * @test 33 * @key headful 34 * @summary Check if a translucent shaped window trigger events correctly. 35 * 36 * Test Description: Check if TRANSLUCENT and PERPIXEL_TRANSPARENT traslucency 37 * types are supported on the current platform. Proceed if both are 38 * supported. Create a window with some components in it and a shape 39 * applied. Apply the shape such that some components are partially 40 * clipped. Set an opacity value less than 1. Check if the components 41 * behave correctly on mouse and key events. Do this test for awt Window. 42 * Expected Result: Mouse and key events must work correctly. Only that portion 43 * of a component within the shape should trigger events. Key events 44 * should be tested for focus events and TextField/TextArea. 45 * 46 * @author mrkam 47 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com) 48 * @library ../../../../lib/testlibrary 49 * @build Common ExtendedRobot 50 * @run main ShapedTranslucentWindowClick 51 */ 52 53public class ShapedTranslucentWindowClick extends Common { 54 55 Component south, center, north; 56 57 volatile BitSet backgroundFlags = new BitSet(11); 58 volatile BitSet southFlags = new BitSet(11); 59 volatile BitSet centerFlags = new BitSet(11); 60 volatile BitSet northFlags = new BitSet(11); 61 static BitSet reference = BitSet.valueOf(new long[] {2047}); // 111 1111 1111 62 63 public static void main(String[] ignored) throws Exception{ 64 if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT) && 65 checkTranslucencyMode(GraphicsDevice.WindowTranslucency.TRANSLUCENT)) 66 new ShapedTranslucentWindowClick(Window.class).doTest(); 67 } 68 69 public ShapedTranslucentWindowClick(Class windowClass) throws Exception { 70 super(windowClass); 71 addListeners(south, southFlags); 72 addListeners(center, centerFlags); 73 addListeners(north, northFlags); 74 addListeners(background, backgroundFlags); 75 } 76 77 @Override 78 public void initGUI() { 79 80 window = new Window(background); 81 south = new Button("South Button"); 82 center = new TextArea("Center Text Area"); 83 north = new TextField("North Text Field"); 84 85 window.setLocation(250, 250); 86 window.setPreferredSize(new Dimension(200, 200)); 87 window.setOpacity(0.7f); 88 applyShape(); 89 window.setLayout(new BorderLayout()); 90 91 window.add(south, BorderLayout.SOUTH); 92 window.add(center, BorderLayout.CENTER); 93 window.add(north, BorderLayout.NORTH); 94 95 window.pack(); 96 window.setVisible(true); 97 window.toFront(); 98 99 System.out.println("Checking " + window.getClass().getName() + "..."); 100 } 101 102 @Override 103 public void doTest() throws Exception { 104 105 robot.waitForIdle(); 106 robot.mouseMove(background.getLocationOnScreen().x+50, background.getLocationOnScreen().y+50); 107 robot.waitForIdle(); 108 robot.click(); 109 110 Point wls = window.getLocationOnScreen(); 111 Point ls; 112 int y; 113 114 robot.waitForIdle(); 115 116 ls = north.getLocationOnScreen(); 117 checkClickAndType(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, northFlags); 118 119 ls = center.getLocationOnScreen(); 120 checkClickAndType(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, centerFlags); 121 122 ls = center.getLocationOnScreen(); 123 checkClickAndType(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, centerFlags); 124 125 ls = south.getLocationOnScreen(); 126 checkClickAndType(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, southFlags); 127 128 ls = north.getLocationOnScreen(); 129 y = ls.y + north.getHeight() / 2; 130 checkClickAndType(wls.x + 200 - (y - wls.y), y, backgroundFlags); 131 132 EventQueue.invokeAndWait(window::toFront); 133 robot.waitForIdle(); 134 135 ls = center.getLocationOnScreen(); 136 y = ls.y + center.getHeight() / 2; 137 checkClickAndType(wls.x + 200 - (y - wls.y), y, backgroundFlags); 138 139 EventQueue.invokeAndWait(window::toFront); 140 robot.waitForIdle(); 141 142 ls = south.getLocationOnScreen(); 143 y = ls.y + south.getHeight() / 2; 144 checkClickAndType(wls.x + 200 - (y - wls.y), y, backgroundFlags); 145 146 EventQueue.invokeAndWait(window::dispose); 147 EventQueue.invokeAndWait(background::dispose); 148 149 robot.waitForIdle(); 150 } 151 152 @Override 153 public void applyShape() { 154 Area shape = new Area(new Rectangle2D.Float(0, 0, 200, 200)); 155 GeneralPath gp; 156 gp = new GeneralPath(); 157 gp.moveTo(190, 0); 158 gp.lineTo(200, 0); 159 gp.lineTo(200, 10); 160 gp.lineTo(10, 200); 161 gp.lineTo(0, 200); 162 gp.lineTo(0, 190); 163 gp.closePath(); 164 shape.subtract(new Area(gp)); 165 166 window.setShape(shape); 167 } 168 169 void checkClickAndType(int x, int y, BitSet bits){ 170 bits.clear(0, 10); 171 172 robot.mouseMove(x, y); 173 robot.click(); 174 robot.dragAndDrop(MouseInfo.getPointerInfo().getLocation(), new Point(x+5, y)); 175 robot.mouseWheel(1); 176 robot.waitForIdle(); 177 178 robot.type('a'); 179 180 robot.mouseMove(350, 50); 181 robot.waitForIdle(); 182 183 //robot.delay(20*1000); 184 if (!bits.equals(reference)){ 185 for( int i = 0; i < 11; i++) 186 System.err.print(( bits.get(i) ? 1 : 0 ) + ", "); 187 System.err.println(); 188 throw new RuntimeException("Bit mask is not fully set: "+bits); 189 } 190 } 191 192 static void addListeners(Component component, BitSet bits) { 193 component.addMouseListener(new MouseListener() { 194 public void mouseClicked(MouseEvent e) { bits.set(0);} 195 public void mousePressed(MouseEvent e) { bits.set(1); } 196 public void mouseReleased(MouseEvent e) { bits.set(2); } 197 public void mouseEntered(MouseEvent e) { bits.set(3); } 198 public void mouseExited(MouseEvent e) { bits.set(4); } 199 }); 200 component.addMouseMotionListener(new MouseMotionListener() { 201 public void mouseDragged(MouseEvent e) { bits.set(5); } 202 public void mouseMoved(MouseEvent e) { bits.set(6); } 203 }); 204 component.addMouseWheelListener((e) -> bits.set(7)); 205 component.addKeyListener(new KeyListener() { 206 public void keyTyped(KeyEvent e) { bits.set(8); } 207 public void keyPressed(KeyEvent e) { bits.set(9); } 208 public void keyReleased(KeyEvent e) { bits.set(10); } 209 }); 210 }; 211} 212