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