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 javax.swing.*;
25 import java.awt.*;
26 import java.awt.event.ComponentAdapter;
27 import java.awt.event.ComponentEvent;
28 import java.awt.event.MouseAdapter;
29 import java.awt.event.MouseEvent;
30 import java.awt.geom.Area;
31 import java.awt.geom.GeneralPath;
32 import java.awt.geom.Rectangle2D;
33 
34 /*
35  * @test
36  * @summary Check if a window set with shape clips the contents
37  * Test Description: Check if PERPIXEL_TRANSPARENT translucency type is supported
38  *      by the current platform. Proceed if it is supported. Apply different types
39  *      of shapes on a Window which contains some awt components. Shape should be
40  *      applied in such a way that some components are partially clipped off. Check
41  *      if the components appear only partially and events work correctly for those
42  *      components - i.e. events occur only on the areas which appear and do not
43  *      occur on the clipped off areas. Events should be checked by clicking on the
44  *      visible and clipped regions. Repeat this for Window, Dialog and Frame.
45  * Expected Result: If PERPIXEL_TRANSPARENT translucency type is supported, clicking
46  *      on clipped region should deliver the event to the background (it should be
47  *      another Window behind the test window)
48  * @author mrkam
49  * @library ../../../../lib/testlibrary
50  * @build Common ExtendedRobot
51  * @run main SetShapeAndClickSwing
52  */
53 
54 public class SetShapeAndClickSwing extends Common {
55 
56     Component south, center, north;
57 
main(String[] args)58     public static void main(String[] args) throws Exception {
59         if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
60             for (Class<Window> windowClass: WINDOWS_TO_TEST)
61                 new SetShapeAndClickSwing(windowClass).doTest();
62     }
63 
SetShapeAndClickSwing(Class windowClass)64     public SetShapeAndClickSwing(Class windowClass) throws Exception {
65         super(windowClass);
66     }
67 
68     @Override
initBackgroundFrame()69     public void initBackgroundFrame() {
70         super.initBackgroundFrame();
71         background.addMouseListener(new MouseAdapter() {
72             @Override
73             public void mouseClicked(MouseEvent e) {
74                 clicked |= 1 << 0;
75             }
76         });
77     }
78 
79     @Override
createSwingComponents()80     public void createSwingComponents() {
81         window.setSize(200,200);
82         window.setLayout(new BorderLayout());
83 
84         south = new JLabel("South");
85         south.addMouseListener(new MouseAdapter() {
86             @Override
87             public void mouseClicked(MouseEvent e) {
88                 clicked |= 1 << 3;
89             }
90         });
91         window.add(south, BorderLayout.SOUTH);
92 
93         center = new JList();
94         center.addMouseListener(new MouseAdapter() {
95             @Override
96             public void mouseClicked(MouseEvent e) {
97                 clicked |= 1 << 2;
98             }
99         });
100         window.add(center, BorderLayout.CENTER);
101 
102         north = new JTextField("North");
103         north.addMouseListener(new MouseAdapter() {
104             @Override
105             public void mouseClicked(MouseEvent e) {
106                 clicked |= 1 << 1;
107             }
108         });
109         window.add(north, BorderLayout.NORTH);
110     }
111 
112     @Override
doTest()113     public void doTest() throws Exception {
114 
115         robot.waitForIdle();
116 
117         Point wls = window.getLocationOnScreen();
118         Point ls;
119         int y;
120         ls = north.getLocationOnScreen();
121         checkClick(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, 1);
122 
123         ls = center.getLocationOnScreen();
124         checkClick(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, 2);
125 
126         ls = south.getLocationOnScreen();
127         checkClick(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, 3);
128 
129         ls = center.getLocationOnScreen();
130         checkClick(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, 2);
131 
132         ls = north.getLocationOnScreen();
133         y = ls.y + north.getHeight() / 2;
134         checkClick(wls.x + 200 - (y - wls.y), y, 0);
135 
136         EventQueue.invokeAndWait(window::toFront);
137         robot.waitForIdle();
138 
139         ls = center.getLocationOnScreen();
140         y = ls.y + center.getHeight() / 2;
141         checkClick(wls.x + 200 - (y - wls.y), y, 0);
142 
143         EventQueue.invokeAndWait(window::toFront);
144         robot.waitForIdle();
145 
146         ls = south.getLocationOnScreen();
147         y = ls.y + south.getHeight() / 2;
148         checkClick(wls.x + 200 - (y - wls.y), y, 0);
149 
150         EventQueue.invokeAndWait(window::dispose);
151         EventQueue.invokeAndWait(background::dispose);
152 
153         robot.waitForIdle();
154     }
155 
156     @Override
applyShape()157     public void applyShape() {
158         Area shape = new Area(new Rectangle2D.Float(0, 0, 200, 200));
159         GeneralPath gp;
160         gp = new GeneralPath();
161         gp.moveTo(190, 0);
162         gp.lineTo(200, 0);
163         gp.lineTo(200, 10);
164         gp.lineTo(10, 200);
165         gp.lineTo(0, 200);
166         gp.lineTo(0, 190);
167         gp.closePath();
168         shape.subtract(new Area(gp));
169 
170         window.setShape(shape);
171     }
172 }
173