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 24 import java.awt.Dialog; 25 import java.awt.Frame; 26 import java.awt.Point; 27 import java.awt.Robot; 28 import java.awt.Window; 29 import java.awt.datatransfer.DataFlavor; 30 import java.awt.datatransfer.Transferable; 31 import java.awt.dnd.DnDConstants; 32 import java.awt.dnd.DragGestureEvent; 33 import java.awt.dnd.DragGestureListener; 34 import java.awt.dnd.DragSource; 35 import java.awt.dnd.DropTarget; 36 import java.awt.dnd.DropTargetDragEvent; 37 import java.awt.dnd.DropTargetDropEvent; 38 import java.awt.dnd.DropTargetEvent; 39 import java.awt.dnd.DropTargetListener; 40 import java.awt.event.InputEvent; 41 import java.awt.event.MouseAdapter; 42 import 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 */ 50 public 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 }