1 /* 2 * Copyright (c) 2005, 2012, 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 7154048 28 * @summary Window created under a mouse does not receive mouse enter event. 29 * Mouse Entered/Exited events are wrongly generated during dragging the window 30 * from one component to another 31 * @library ../../regtesthelpers 32 * @build Util 33 * @author alexandr.scherbatiy area=awt.event 34 * @run main DragWindowTest 35 */ 36 37 import java.awt.*; 38 import java.awt.event.*; 39 import javax.swing.*; 40 41 import java.util.concurrent.*; 42 import sun.awt.SunToolkit; 43 44 import test.java.awt.regtesthelpers.Util; 45 46 public class DragWindowTest { 47 48 private static volatile int dragWindowMouseEnteredCount = 0; 49 private static volatile int dragWindowMouseReleasedCount = 0; 50 private static volatile int buttonMouseEnteredCount = 0; 51 private static volatile int labelMouseReleasedCount = 0; 52 private static MyDragWindow dragWindow; 53 private static JLabel label; 54 private static JButton button; 55 56 public static void main(String[] args) throws Exception { 57 58 SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); 59 Robot robot = new Robot(); 60 robot.setAutoDelay(50); 61 62 SwingUtilities.invokeAndWait(new Runnable() { 63 64 @Override 65 public void run() { 66 createAndShowGUI(); 67 } 68 }); 69 70 toolkit.realSync(); 71 72 Point pointToClick = Util.invokeOnEDT(new Callable<Point>() { 73 74 @Override 75 public Point call() throws Exception { 76 return getCenterPoint(label); 77 } 78 }); 79 80 81 robot.mouseMove(pointToClick.x, pointToClick.y); 82 robot.mousePress(InputEvent.BUTTON1_MASK); 83 toolkit.realSync(); 84 85 if (dragWindowMouseEnteredCount != 1) { 86 throw new RuntimeException("No MouseEntered event on Drag Window!"); 87 } 88 89 Point pointToDrag = Util.invokeOnEDT(new Callable<Point>() { 90 91 @Override 92 public Point call() throws Exception { 93 button.addMouseListener(new ButtonMouseListener()); 94 return getCenterPoint(button); 95 } 96 }); 97 98 robot.mouseMove(pointToDrag.x, pointToDrag.y); 99 toolkit.realSync(); 100 101 if (buttonMouseEnteredCount != 0) { 102 throw new RuntimeException("Extra MouseEntered event on button!"); 103 } 104 105 robot.mouseRelease(InputEvent.BUTTON1_MASK); 106 toolkit.realSync(); 107 108 if (labelMouseReleasedCount != 1) { 109 throw new RuntimeException("No MouseReleased event on label!"); 110 } 111 112 } 113 114 private static Point getCenterPoint(Component comp) { 115 Point p = comp.getLocationOnScreen(); 116 Rectangle rect = comp.getBounds(); 117 return new Point(p.x + rect.width / 2, p.y + rect.height / 2); 118 } 119 120 private static void createAndShowGUI() { 121 122 JFrame frame = new JFrame("Main Frame"); 123 frame.setSize(300, 200); 124 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 125 126 label = new JLabel("Label"); 127 128 LabelMouseListener listener = new LabelMouseListener(frame); 129 label.addMouseListener(listener); 130 label.addMouseMotionListener(listener); 131 132 button = new JButton("Button"); 133 Panel panel = new Panel(new BorderLayout()); 134 135 panel.add(label, BorderLayout.NORTH); 136 panel.add(button, BorderLayout.CENTER); 137 138 frame.getContentPane().add(panel); 139 frame.setVisible(true); 140 141 } 142 143 private static Point getAbsoluteLocation(MouseEvent e) { 144 return new Point(e.getXOnScreen(), e.getYOnScreen()); 145 } 146 147 static class MyDragWindow extends Window { 148 149 static int d = 30; 150 151 public MyDragWindow(Window parent, Point location) { 152 super(parent); 153 setSize(150, 150); 154 setVisible(true); 155 JPanel panel = new JPanel(); 156 add(panel); 157 setLocation(location.x - d, location.y - d); 158 addMouseListener(new DragWindowMouseListener()); 159 } 160 161 void dragTo(Point point) { 162 setLocation(point.x - d, point.y - d); 163 } 164 } 165 166 static class LabelMouseListener extends MouseAdapter { 167 168 Point origin; 169 Window parent; 170 171 public LabelMouseListener(Window parent) { 172 this.parent = parent; 173 } 174 175 @Override 176 public void mousePressed(MouseEvent e) { 177 if (dragWindow == null) { 178 dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e)); 179 } else { 180 dragWindow.setVisible(true); 181 dragWindow.dragTo(getAbsoluteLocation(e)); 182 } 183 } 184 185 @Override 186 public void mouseReleased(MouseEvent e) { 187 labelMouseReleasedCount++; 188 if (dragWindow != null) { 189 dragWindow.setVisible(false); 190 } 191 } 192 193 public void mouseDragged(MouseEvent e) { 194 if (dragWindow != null) { 195 dragWindow.dragTo(getAbsoluteLocation(e)); 196 } 197 } 198 } 199 200 static class DragWindowMouseListener extends MouseAdapter { 201 202 @Override 203 public void mouseEntered(MouseEvent e) { 204 dragWindowMouseEnteredCount++; 205 } 206 207 @Override 208 public void mouseReleased(MouseEvent e) { 209 dragWindowMouseReleasedCount++; 210 } 211 } 212 213 static class ButtonMouseListener extends MouseAdapter { 214 215 @Override 216 public void mouseEntered(MouseEvent e) { 217 buttonMouseEnteredCount++; 218 } 219 } 220 }