MissingEventsOnModalDialogTest.java revision 12849:34c93fd32c20
1/*
2 * Copyright (c) 2015, 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.Dialog;
25import java.awt.Frame;
26import java.awt.Point;
27import java.awt.Robot;
28import java.awt.Window;
29import java.awt.datatransfer.DataFlavor;
30import java.awt.datatransfer.Transferable;
31import java.awt.dnd.DnDConstants;
32import java.awt.dnd.DragGestureEvent;
33import java.awt.dnd.DragGestureListener;
34import java.awt.dnd.DragSource;
35import java.awt.dnd.DropTarget;
36import java.awt.dnd.DropTargetDragEvent;
37import java.awt.dnd.DropTargetDropEvent;
38import java.awt.dnd.DropTargetEvent;
39import java.awt.dnd.DropTargetListener;
40import java.awt.event.InputEvent;
41import java.awt.event.MouseAdapter;
42import java.awt.event.MouseEvent;
43
44/*
45 * @test
46 * @bug 8134917
47 * @summary [macosx] JOptionPane doesn't receive mouse events when opened from a drop event
48 * @author Alexandr Scherbatiy
49 */
50public class MissingEventsOnModalDialogTest {
51
52    private static volatile boolean passed = false;
53
54    public static void main(String[] args) throws Exception {
55        Frame sourceFrame = createFrame("Source Frame", 0, 0);
56        Frame targetFrame = createFrame("Target Frame", 250, 250);
57
58        DragSource defaultDragSource
59                = DragSource.getDefaultDragSource();
60        defaultDragSource.createDefaultDragGestureRecognizer(sourceFrame,
61                DnDConstants.ACTION_COPY_OR_MOVE,
62                new TestDragGestureListener());
63        new DropTarget(targetFrame, DnDConstants.ACTION_COPY_OR_MOVE,
64                new TestDropTargetListener(targetFrame));
65
66        Robot robot = new Robot();
67        robot.setAutoDelay(50);
68
69        sourceFrame.toFront();
70        robot.waitForIdle();
71
72        Point point = getCenterPoint(sourceFrame);
73        robot.mouseMove(point.x, point.y);
74        robot.waitForIdle();
75
76        mouseDragAndDrop(robot, point, getCenterPoint(targetFrame));
77
78        long time = System.currentTimeMillis() + 200;
79
80        while (!passed) {
81            if (time < System.currentTimeMillis()) {
82                sourceFrame.dispose();
83                targetFrame.dispose();
84                throw new RuntimeException("Mouse clicked event is lost!");
85            }
86            Thread.sleep(10);
87        }
88        sourceFrame.dispose();
89        targetFrame.dispose();
90    }
91
92    private static Frame createFrame(String title, int x, int y) {
93        Frame frame = new Frame();
94        frame.setSize(200, 200);
95        frame.setLocation(x, y);
96        frame.setTitle(title);
97        frame.setVisible(true);
98        return frame;
99    }
100
101    private static Point getCenterPoint(Window window) {
102        Point centerPoint = window.getLocationOnScreen();
103        centerPoint.translate(window.getWidth() / 2, window.getHeight() / 2);
104        return centerPoint;
105    }
106
107    public static void mouseDragAndDrop(Robot robot, Point from, Point to) {
108        mouseDND(robot, from.x, from.y, to.x, to.y);
109    }
110
111    public static void mouseDND(Robot robot, int x1, int y1, int x2, int y2) {
112
113        int N = 20;
114        int x = x1;
115        int y = y1;
116        int dx = (x2 - x1) / N;
117        int dy = (y2 - y1) / N;
118
119        robot.mousePress(InputEvent.BUTTON1_MASK);
120
121        for (int i = 0; i < N; i++) {
122            robot.mouseMove(x += dx, y += dy);
123        }
124
125        robot.mouseRelease(InputEvent.BUTTON1_MASK);
126    }
127
128    private static class TestDragGestureListener implements DragGestureListener {
129
130        public void dragGestureRecognized(DragGestureEvent dge) {
131            dge.startDrag(null, new StringTransferable());
132        }
133    }
134
135    static class StringTransferable implements Transferable {
136
137        @Override
138        public DataFlavor[] getTransferDataFlavors() {
139            return new DataFlavor[]{DataFlavor.stringFlavor};
140        }
141
142        @Override
143        public boolean isDataFlavorSupported(DataFlavor flavor) {
144            return flavor.equals(DataFlavor.stringFlavor);
145        }
146
147        @Override
148        public Object getTransferData(DataFlavor flavor) {
149            return "Hello World!";
150        }
151    }
152
153    private static class TestDropTargetListener implements DropTargetListener {
154
155        private final Frame targetFrame;
156
157        public TestDropTargetListener(Frame targetFrame) {
158            this.targetFrame = targetFrame;
159        }
160
161        @Override
162        public void dragEnter(DropTargetDragEvent dtde) {
163            dtde.acceptDrag(dtde.getDropAction());
164        }
165
166        @Override
167        public void dragOver(DropTargetDragEvent dtde) {
168            dtde.acceptDrag(dtde.getDropAction());
169        }
170
171        @Override
172        public void dropActionChanged(DropTargetDragEvent dtde) {
173            dtde.acceptDrag(dtde.getDropAction());
174        }
175
176        @Override
177        public void dragExit(DropTargetEvent dte) {
178        }
179
180        @Override
181        public void drop(DropTargetDropEvent dtde) {
182            dtde.acceptDrop(dtde.getDropAction());
183            showModalDialog(targetFrame);
184            dtde.dropComplete(true);
185        }
186    }
187
188    private static void showModalDialog(Frame targetFrame) {
189
190        Dialog dialog = new Dialog(targetFrame, true);
191
192        dialog.addMouseListener(new MouseAdapter() {
193
194            @Override
195            public void mouseClicked(MouseEvent e) {
196                passed = true;
197                dialog.dispose();
198            }
199        });
200
201        dialog.setSize(400, 300);
202        dialog.setTitle("Modal Dialog!");
203
204        clickOnModalDialog(dialog);
205        dialog.setVisible(true);
206    }
207
208    private static void clickOnModalDialog(Dialog dialog) {
209        new Thread(() -> {
210            clickOnDialog(dialog);
211        }).start();
212    }
213
214    private static void clickOnDialog(Dialog dialog) {
215        try {
216            long time = System.currentTimeMillis() + 200;
217
218            while (!dialog.isVisible()) {
219                if (time < System.currentTimeMillis()) {
220                    throw new RuntimeException("Dialog is not visible!");
221                }
222                Thread.sleep(10);
223            }
224
225            Point point = getCenterPoint(dialog);
226            Robot robot = new Robot();
227            robot.setAutoDelay(50);
228
229            robot.mouseMove(point.x, point.y);
230            robot.mousePress(InputEvent.BUTTON1_MASK);
231            robot.mouseRelease(InputEvent.BUTTON1_MASK);
232
233        } catch (Exception e) {
234            throw new RuntimeException(e);
235        }
236    }
237}
238