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