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