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 }