1 /* 2 * Copyright (c) 2013, 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 8027913 28 * @library ../../regtesthelpers 29 * @build Util 30 * @compile MissingDragExitEventTest.java 31 * @run main/othervm MissingDragExitEventTest 32 * @author Sergey Bylokhov 33 */ 34 35 import java.awt.Color; 36 import java.awt.Point; 37 import java.awt.Robot; 38 import java.awt.Toolkit; 39 import java.awt.dnd.DnDConstants; 40 import java.awt.dnd.DropTarget; 41 import java.awt.dnd.DropTargetAdapter; 42 import java.awt.dnd.DropTargetDragEvent; 43 import java.awt.dnd.DropTargetDropEvent; 44 import java.awt.dnd.DropTargetEvent; 45 import java.awt.event.InputEvent; 46 import java.awt.event.MouseAdapter; 47 import java.awt.event.MouseEvent; 48 49 import javax.swing.JFrame; 50 import javax.swing.JTextArea; 51 import javax.swing.SwingUtilities; 52 53 import sun.awt.SunToolkit; 54 import test.java.awt.regtesthelpers.Util; 55 56 public class MissingDragExitEventTest { 57 58 private static volatile JFrame frame; 59 private static boolean FAILED; 60 private static boolean MOUSE_ENTERED_DT; 61 private static boolean MOUSE_ENTERED; 62 private static boolean MOUSE_EXIT_TD; 63 private static boolean MOUSE_EXIT; 64 private static int SIZE = 300; 65 66 private static void initAndShowUI() { 67 frame = new JFrame("Test frame"); 68 69 frame.setSize(SIZE, SIZE); 70 frame.setLocationRelativeTo(null); 71 final JTextArea jta = new JTextArea(); 72 jta.setBackground(Color.RED); 73 frame.add(jta); 74 jta.setText("1234567890"); 75 jta.setFont(jta.getFont().deriveFont(150f)); 76 jta.setDragEnabled(true); 77 jta.selectAll(); 78 jta.setDropTarget(new DropTarget(jta, DnDConstants.ACTION_COPY, 79 new TestdropTargetListener())); 80 jta.addMouseListener(new TestMouseAdapter()); 81 frame.setVisible(true); 82 } 83 84 public static void main(final String[] args) throws Exception { 85 try { 86 final Robot r = new Robot(); 87 r.setAutoDelay(50); 88 r.mouseMove(100, 100); 89 Util.waitForIdle(r); 90 91 SwingUtilities.invokeAndWait(new Runnable() { 92 @Override 93 public void run() { 94 initAndShowUI(); 95 } 96 }); 97 98 final Point inside = new Point(frame.getLocationOnScreen()); 99 inside.translate(20, SIZE / 2); 100 final Point outer = new Point(inside); 101 outer.translate(-40, 0); 102 r.mouseMove(inside.x, inside.y); 103 r.mousePress(InputEvent.BUTTON1_MASK); 104 try { 105 for (int i = 0; i < 3; ++i) { 106 Util.mouseMove(r, inside, outer); 107 Util.mouseMove(r, outer, inside); 108 } 109 } finally { 110 r.mouseRelease(InputEvent.BUTTON1_MASK); 111 } 112 sleep(); 113 114 if (FAILED || !MOUSE_ENTERED || !MOUSE_ENTERED_DT || !MOUSE_EXIT 115 || !MOUSE_EXIT_TD) { 116 throw new RuntimeException("Failed"); 117 } 118 } finally { 119 if (frame != null) { 120 frame.dispose(); 121 } 122 } 123 } 124 125 private static void sleep() { 126 try { 127 Thread.sleep(10000); 128 } catch (InterruptedException ignored) { 129 } 130 ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); 131 } 132 133 static class TestdropTargetListener extends DropTargetAdapter { 134 135 private volatile boolean inside; 136 137 @Override 138 public void dragEnter(final DropTargetDragEvent dtde) { 139 if (inside) { 140 FAILED = true; 141 Thread.dumpStack(); 142 } 143 inside = true; 144 MOUSE_ENTERED_DT = true; 145 try { 146 Thread.sleep(10000); // we should have time to leave a component 147 } catch (InterruptedException ignored) { 148 } 149 } 150 151 @Override 152 public void dragOver(final DropTargetDragEvent dtde) { 153 if (!inside) { 154 FAILED = true; 155 Thread.dumpStack(); 156 } 157 } 158 159 @Override 160 public void dragExit(final DropTargetEvent dte) { 161 if (!inside) { 162 FAILED = true; 163 Thread.dumpStack(); 164 } 165 inside = false; 166 MOUSE_EXIT_TD = true; 167 } 168 169 @Override 170 public void drop(final DropTargetDropEvent dtde) { 171 if (!inside) { 172 FAILED = true; 173 Thread.dumpStack(); 174 } 175 inside = false; 176 } 177 } 178 179 static class TestMouseAdapter extends MouseAdapter { 180 181 private volatile boolean inside; 182 183 @Override 184 public void mouseEntered(final MouseEvent e) { 185 if (inside) { 186 FAILED = true; 187 Thread.dumpStack(); 188 } 189 inside = true; 190 MOUSE_ENTERED = true; 191 } 192 193 @Override 194 public void mouseExited(final MouseEvent e) { 195 if (!inside) { 196 FAILED = true; 197 Thread.dumpStack(); 198 } 199 inside = false; 200 MOUSE_EXIT = true; 201 } 202 } 203 }