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 
  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         Robot robot = new Robot();
  58         robot.setAutoDelay(50);
  59 
  60         SwingUtilities.invokeAndWait(new Runnable() {
  61 
  62             @Override
  63             public void run() {
  64                 createAndShowGUI();
  65             }
  66         });
  67 
  68         robot.waitForIdle();
  69 
  70         Point pointToClick = Util.invokeOnEDT(new Callable<Point>() {
  71 
  72             @Override
  73             public Point call() throws Exception {
  74                 return getCenterPoint(label);
  75             }
  76         });
  77 
  78 
  79         robot.mouseMove(pointToClick.x, pointToClick.y);
  80         robot.mousePress(InputEvent.BUTTON1_MASK);
  81         robot.waitForIdle();
  82 
  83         if (dragWindowMouseEnteredCount != 1) {
  84             throw new RuntimeException("No MouseEntered event on Drag Window!");
  85         }
  86 
  87         Point pointToDrag = Util.invokeOnEDT(new Callable<Point>() {
  88 
  89             @Override
  90             public Point call() throws Exception {
  91                 button.addMouseListener(new ButtonMouseListener());
  92                 return getCenterPoint(button);
  93             }
  94         });
  95 
  96         robot.mouseMove(pointToDrag.x, pointToDrag.y);
  97         robot.waitForIdle();
  98 
  99         if (buttonMouseEnteredCount != 0) {
 100             throw new RuntimeException("Extra MouseEntered event on button!");
 101         }
 102 
 103         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 104         robot.waitForIdle();
 105 
 106         if (labelMouseReleasedCount != 1) {
 107             throw new RuntimeException("No MouseReleased event on label!");
 108         }
 109 
 110     }
 111 
 112     private static Point getCenterPoint(Component comp) {
 113         Point p = comp.getLocationOnScreen();
 114         Rectangle rect = comp.getBounds();
 115         return new Point(p.x + rect.width / 2, p.y + rect.height / 2);
 116     }
 117 
 118     private static void createAndShowGUI() {
 119 
 120         JFrame frame = new JFrame("Main Frame");
 121         frame.setSize(300, 200);
 122         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 123 
 124         label = new JLabel("Label");
 125 
 126         LabelMouseListener listener = new LabelMouseListener(frame);
 127         label.addMouseListener(listener);
 128         label.addMouseMotionListener(listener);
 129 
 130         button = new JButton("Button");
 131         Panel panel = new Panel(new BorderLayout());
 132 
 133         panel.add(label, BorderLayout.NORTH);
 134         panel.add(button, BorderLayout.CENTER);
 135 
 136         frame.getContentPane().add(panel);
 137         frame.setVisible(true);
 138 
 139     }
 140 
 141     private static Point getAbsoluteLocation(MouseEvent e) {
 142         return new Point(e.getXOnScreen(), e.getYOnScreen());
 143     }
 144 
 145     static class MyDragWindow extends Window {
 146 
 147         static int d = 30;
 148 
 149         public MyDragWindow(Window parent, Point location) {
 150             super(parent);
 151             setSize(150, 150);
 152             setVisible(true);
 153             JPanel panel = new JPanel();
 154             add(panel);
 155             setLocation(location.x - d, location.y - d);
 156             addMouseListener(new DragWindowMouseListener());
 157         }
 158 
 159         void dragTo(Point point) {
 160             setLocation(point.x - d, point.y - d);
 161         }
 162     }
 163 
 164     static class LabelMouseListener extends MouseAdapter {
 165 
 166         Point origin;
 167         Window parent;
 168 
 169         public LabelMouseListener(Window parent) {
 170             this.parent = parent;
 171         }
 172 
 173         @Override
 174         public void mousePressed(MouseEvent e) {
 175             if (dragWindow == null) {
 176                 dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e));
 177             } else {
 178                 dragWindow.setVisible(true);
 179                 dragWindow.dragTo(getAbsoluteLocation(e));
 180             }
 181         }
 182 
 183         @Override
 184         public void mouseReleased(MouseEvent e) {
 185             labelMouseReleasedCount++;
 186             if (dragWindow != null) {
 187                 dragWindow.setVisible(false);
 188             }
 189         }
 190 
 191         public void mouseDragged(MouseEvent e) {
 192             if (dragWindow != null) {
 193                 dragWindow.dragTo(getAbsoluteLocation(e));
 194             }
 195         }
 196     }
 197 
 198     static class DragWindowMouseListener extends MouseAdapter {
 199 
 200         @Override
 201         public void mouseEntered(MouseEvent e) {
 202             dragWindowMouseEnteredCount++;
 203         }
 204 
 205         @Override
 206         public void mouseReleased(MouseEvent e) {
 207             dragWindowMouseReleasedCount++;
 208         }
 209     }
 210 
 211     static class ButtonMouseListener extends MouseAdapter {
 212 
 213         @Override
 214         public void mouseEntered(MouseEvent e) {
 215             buttonMouseEnteredCount++;
 216         }
 217     }
 218 }