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