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 * @key headful 47 * @bug 8134917 48 * @summary [macosx] JOptionPane doesn't receive mouse events when opened from a drop event 49 * @author Alexandr Scherbatiy 50 */ 51 public class MissingEventsOnModalDialogTest { 52 53 private static volatile boolean passed = false; 54 55 public static void main(String[] args) throws Exception { 56 Frame sourceFrame = createFrame("Source Frame", 0, 0); 57 Frame targetFrame = createFrame("Target Frame", 250, 250); 58 59 DragSource defaultDragSource 60 = DragSource.getDefaultDragSource(); 61 defaultDragSource.createDefaultDragGestureRecognizer(sourceFrame, 62 DnDConstants.ACTION_COPY_OR_MOVE, 63 new TestDragGestureListener()); 64 new DropTarget(targetFrame, DnDConstants.ACTION_COPY_OR_MOVE, 65 new TestDropTargetListener(targetFrame)); 66 67 Robot robot = new Robot(); 68 robot.setAutoDelay(50); 69 70 sourceFrame.toFront(); 71 robot.waitForIdle(); 72 73 Point point = getCenterPoint(sourceFrame); 74 robot.mouseMove(point.x, point.y); 75 robot.waitForIdle(); 76 77 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 }