1/*
2 * Copyright (c) 2005, 2012, 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/*
25 * @test
26 * @key headful
27 * @bug 7154048
28 * @summary Window created under a mouse does not receive mouse enter event.
29 *     Mouse Entered/Exited events are wrongly generated during dragging the window
30 *     from one component to another
31 * @library ../../regtesthelpers
32 * @build Util
33 * @author alexandr.scherbatiy area=awt.event
34 * @run main DragWindowTest
35 */
36
37import java.awt.*;
38import java.awt.event.*;
39import javax.swing.*;
40
41import java.util.concurrent.*;
42
43import test.java.awt.regtesthelpers.Util;
44
45public class DragWindowTest {
46
47    private static volatile int dragWindowMouseEnteredCount = 0;
48    private static volatile int dragWindowMouseReleasedCount = 0;
49    private static volatile int buttonMouseEnteredCount = 0;
50    private static volatile int labelMouseReleasedCount = 0;
51    private static MyDragWindow dragWindow;
52    private static JLabel label;
53    private static JButton button;
54
55    public static void main(String[] args) throws Exception {
56
57        Robot robot = new Robot();
58        robot.setAutoDelay(50);
59
60        SwingUtilities.invokeAndWait(new Runnable() {
61
62            @Override
63            public void run() {
64                createAndShowGUI();
65            }
66        });
67
68        robot.waitForIdle();
69
70        Point pointToClick = Util.invokeOnEDT(new Callable<Point>() {
71
72            @Override
73            public Point call() throws Exception {
74                return getCenterPoint(label);
75            }
76        });
77
78
79        robot.mouseMove(pointToClick.x, pointToClick.y);
80        robot.mousePress(InputEvent.BUTTON1_MASK);
81        robot.waitForIdle();
82
83        if (dragWindowMouseEnteredCount != 1) {
84            throw new RuntimeException("No MouseEntered event on Drag Window!");
85        }
86
87        Point pointToDrag = Util.invokeOnEDT(new Callable<Point>() {
88
89            @Override
90            public Point call() throws Exception {
91                button.addMouseListener(new ButtonMouseListener());
92                return getCenterPoint(button);
93            }
94        });
95
96        robot.mouseMove(pointToDrag.x, pointToDrag.y);
97        robot.waitForIdle();
98
99        if (buttonMouseEnteredCount != 0) {
100            throw new RuntimeException("Extra MouseEntered event on button!");
101        }
102
103        robot.mouseRelease(InputEvent.BUTTON1_MASK);
104        robot.waitForIdle();
105
106        if (labelMouseReleasedCount != 1) {
107            throw new RuntimeException("No MouseReleased event on label!");
108        }
109
110    }
111
112    private static Point getCenterPoint(Component comp) {
113        Point p = comp.getLocationOnScreen();
114        Rectangle rect = comp.getBounds();
115        return new Point(p.x + rect.width / 2, p.y + rect.height / 2);
116    }
117
118    private static void createAndShowGUI() {
119
120        JFrame frame = new JFrame("Main Frame");
121        frame.setSize(300, 200);
122        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
123
124        label = new JLabel("Label");
125
126        LabelMouseListener listener = new LabelMouseListener(frame);
127        label.addMouseListener(listener);
128        label.addMouseMotionListener(listener);
129
130        button = new JButton("Button");
131        Panel panel = new Panel(new BorderLayout());
132
133        panel.add(label, BorderLayout.NORTH);
134        panel.add(button, BorderLayout.CENTER);
135
136        frame.getContentPane().add(panel);
137        frame.setVisible(true);
138
139    }
140
141    private static Point getAbsoluteLocation(MouseEvent e) {
142        return new Point(e.getXOnScreen(), e.getYOnScreen());
143    }
144
145    static class MyDragWindow extends Window {
146
147        static int d = 30;
148
149        public MyDragWindow(Window parent, Point location) {
150            super(parent);
151            setSize(150, 150);
152            setVisible(true);
153            JPanel panel = new JPanel();
154            add(panel);
155            setLocation(location.x - d, location.y - d);
156            addMouseListener(new DragWindowMouseListener());
157        }
158
159        void dragTo(Point point) {
160            setLocation(point.x - d, point.y - d);
161        }
162    }
163
164    static class LabelMouseListener extends MouseAdapter {
165
166        Point origin;
167        Window parent;
168
169        public LabelMouseListener(Window parent) {
170            this.parent = parent;
171        }
172
173        @Override
174        public void mousePressed(MouseEvent e) {
175            if (dragWindow == null) {
176                dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e));
177            } else {
178                dragWindow.setVisible(true);
179                dragWindow.dragTo(getAbsoluteLocation(e));
180            }
181        }
182
183        @Override
184        public void mouseReleased(MouseEvent e) {
185            labelMouseReleasedCount++;
186            if (dragWindow != null) {
187                dragWindow.setVisible(false);
188            }
189        }
190
191        public void mouseDragged(MouseEvent e) {
192            if (dragWindow != null) {
193                dragWindow.dragTo(getAbsoluteLocation(e));
194            }
195        }
196    }
197
198    static class DragWindowMouseListener extends MouseAdapter {
199
200        @Override
201        public void mouseEntered(MouseEvent e) {
202            dragWindowMouseEnteredCount++;
203        }
204
205        @Override
206        public void mouseReleased(MouseEvent e) {
207            dragWindowMouseReleasedCount++;
208        }
209    }
210
211    static class ButtonMouseListener extends MouseAdapter {
212
213        @Override
214        public void mouseEntered(MouseEvent e) {
215            buttonMouseEnteredCount++;
216        }
217    }
218}
219