MissingEventsOnModalDialogTest.java revision 14851:980da45565c8
197403Sobrien/*
297403Sobrien * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
397403Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
497403Sobrien *
597403Sobrien * This code is free software; you can redistribute it and/or modify it
697403Sobrien * under the terms of the GNU General Public License version 2 only, as
797403Sobrien * published by the Free Software Foundation.
897403Sobrien *
997403Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
1097403Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1197403Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1297403Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1397403Sobrien * accompanied this code).
1497403Sobrien *
1597403Sobrien * You should have received a copy of the GNU General Public License version
1697403Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
1797403Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1897403Sobrien *
1997403Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2097403Sobrien * or visit www.oracle.com if you need additional information or have any
2197403Sobrien * questions.
2297403Sobrien */
2397403Sobrien
2497403Sobrienimport java.awt.Dialog;
2597403Sobrienimport java.awt.Frame;
2697403Sobrienimport java.awt.Point;
2797403Sobrienimport java.awt.Robot;
2897403Sobrienimport java.awt.Window;
2997403Sobrienimport java.awt.datatransfer.DataFlavor;
3097403Sobrienimport java.awt.datatransfer.Transferable;
3197403Sobrienimport java.awt.dnd.DnDConstants;
3297403Sobrienimport java.awt.dnd.DragGestureEvent;
3397403Sobrienimport java.awt.dnd.DragGestureListener;
3497403Sobrienimport java.awt.dnd.DragSource;
3597403Sobrienimport java.awt.dnd.DropTarget;
3697403Sobrienimport java.awt.dnd.DropTargetDragEvent;
3797403Sobrienimport java.awt.dnd.DropTargetDropEvent;
3897403Sobrienimport java.awt.dnd.DropTargetEvent;
3997403Sobrienimport java.awt.dnd.DropTargetListener;
4097403Sobrienimport java.awt.event.InputEvent;
4197403Sobrienimport java.awt.event.MouseAdapter;
4297403Sobrienimport java.awt.event.MouseEvent;
4397403Sobrien
4497403Sobrien/*
4597403Sobrien * @test
4697403Sobrien * @key headful
4797403Sobrien * @bug 8134917
4897403Sobrien * @summary [macosx] JOptionPane doesn't receive mouse events when opened from a drop event
4997403Sobrien * @author Alexandr Scherbatiy
5097403Sobrien */
5197403Sobrienpublic class MissingEventsOnModalDialogTest {
5297403Sobrien
5397403Sobrien    private static volatile boolean passed = false;
5497403Sobrien
5597403Sobrien    public static void main(String[] args) throws Exception {
5697403Sobrien        Frame sourceFrame = createFrame("Source Frame", 0, 0);
5797403Sobrien        Frame targetFrame = createFrame("Target Frame", 250, 250);
5897403Sobrien
5997403Sobrien        DragSource defaultDragSource
6097403Sobrien                = DragSource.getDefaultDragSource();
6197403Sobrien        defaultDragSource.createDefaultDragGestureRecognizer(sourceFrame,
6297403Sobrien                DnDConstants.ACTION_COPY_OR_MOVE,
6397403Sobrien                new TestDragGestureListener());
6497403Sobrien        new DropTarget(targetFrame, DnDConstants.ACTION_COPY_OR_MOVE,
6597403Sobrien                new TestDropTargetListener(targetFrame));
6697403Sobrien
6797403Sobrien        Robot robot = new Robot();
6897403Sobrien        robot.setAutoDelay(50);
6997403Sobrien
7097403Sobrien        sourceFrame.toFront();
7197403Sobrien        robot.waitForIdle();
7297403Sobrien
7397403Sobrien        Point point = getCenterPoint(sourceFrame);
7497403Sobrien        robot.mouseMove(point.x, point.y);
7597403Sobrien        robot.waitForIdle();
7697403Sobrien
7797403Sobrien        mouseDragAndDrop(robot, point, getCenterPoint(targetFrame));
78
79        long time = System.currentTimeMillis() + 200;
80
81        while (!passed) {
82            if (time < System.currentTimeMillis()) {
83                sourceFrame.dispose();
84                targetFrame.dispose();
85                throw new RuntimeException("Mouse clicked event is lost!");
86            }
87            Thread.sleep(10);
88        }
89        sourceFrame.dispose();
90        targetFrame.dispose();
91    }
92
93    private static Frame createFrame(String title, int x, int y) {
94        Frame frame = new Frame();
95        frame.setSize(200, 200);
96        frame.setLocation(x, y);
97        frame.setTitle(title);
98        frame.setVisible(true);
99        return frame;
100    }
101
102    private static Point getCenterPoint(Window window) {
103        Point centerPoint = window.getLocationOnScreen();
104        centerPoint.translate(window.getWidth() / 2, window.getHeight() / 2);
105        return centerPoint;
106    }
107
108    public static void mouseDragAndDrop(Robot robot, Point from, Point to) {
109        mouseDND(robot, from.x, from.y, to.x, to.y);
110    }
111
112    public static void mouseDND(Robot robot, int x1, int y1, int x2, int y2) {
113
114        int N = 20;
115        int x = x1;
116        int y = y1;
117        int dx = (x2 - x1) / N;
118        int dy = (y2 - y1) / N;
119
120        robot.mousePress(InputEvent.BUTTON1_MASK);
121
122        for (int i = 0; i < N; i++) {
123            robot.mouseMove(x += dx, y += dy);
124        }
125
126        robot.mouseRelease(InputEvent.BUTTON1_MASK);
127    }
128
129    private static class TestDragGestureListener implements DragGestureListener {
130
131        public void dragGestureRecognized(DragGestureEvent dge) {
132            dge.startDrag(null, new StringTransferable());
133        }
134    }
135
136    static class StringTransferable implements Transferable {
137
138        @Override
139        public DataFlavor[] getTransferDataFlavors() {
140            return new DataFlavor[]{DataFlavor.stringFlavor};
141        }
142
143        @Override
144        public boolean isDataFlavorSupported(DataFlavor flavor) {
145            return flavor.equals(DataFlavor.stringFlavor);
146        }
147
148        @Override
149        public Object getTransferData(DataFlavor flavor) {
150            return "Hello World!";
151        }
152    }
153
154    private static class TestDropTargetListener implements DropTargetListener {
155
156        private final Frame targetFrame;
157
158        public TestDropTargetListener(Frame targetFrame) {
159            this.targetFrame = targetFrame;
160        }
161
162        @Override
163        public void dragEnter(DropTargetDragEvent dtde) {
164            dtde.acceptDrag(dtde.getDropAction());
165        }
166
167        @Override
168        public void dragOver(DropTargetDragEvent dtde) {
169            dtde.acceptDrag(dtde.getDropAction());
170        }
171
172        @Override
173        public void dropActionChanged(DropTargetDragEvent dtde) {
174            dtde.acceptDrag(dtde.getDropAction());
175        }
176
177        @Override
178        public void dragExit(DropTargetEvent dte) {
179        }
180
181        @Override
182        public void drop(DropTargetDropEvent dtde) {
183            dtde.acceptDrop(dtde.getDropAction());
184            showModalDialog(targetFrame);
185            dtde.dropComplete(true);
186        }
187    }
188
189    private static void showModalDialog(Frame targetFrame) {
190
191        Dialog dialog = new Dialog(targetFrame, true);
192
193        dialog.addMouseListener(new MouseAdapter() {
194
195            @Override
196            public void mouseClicked(MouseEvent e) {
197                passed = true;
198                dialog.dispose();
199            }
200        });
201
202        dialog.setSize(400, 300);
203        dialog.setTitle("Modal Dialog!");
204
205        clickOnModalDialog(dialog);
206        dialog.setVisible(true);
207    }
208
209    private static void clickOnModalDialog(Dialog dialog) {
210        new Thread(() -> {
211            clickOnDialog(dialog);
212        }).start();
213    }
214
215    private static void clickOnDialog(Dialog dialog) {
216        try {
217            long time = System.currentTimeMillis() + 200;
218
219            while (!dialog.isVisible()) {
220                if (time < System.currentTimeMillis()) {
221                    throw new RuntimeException("Dialog is not visible!");
222                }
223                Thread.sleep(10);
224            }
225
226            Point point = getCenterPoint(dialog);
227            Robot robot = new Robot();
228            robot.setAutoDelay(50);
229
230            robot.mouseMove(point.x, point.y);
231            robot.mousePress(InputEvent.BUTTON1_MASK);
232            robot.mouseRelease(InputEvent.BUTTON1_MASK);
233
234        } catch (Exception e) {
235            throw new RuntimeException(e);
236        }
237    }
238}
239