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