1 /*
   2  * Copyright (c) 2007, 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 6267983
  27   @summary PIT: MouseClicked is triggered when the mouse is released outside the tray icon, Win32
  28   @author dmitry.cherepanov@... area=awt.event
  29   @run applet MouseClickTest.html
  30 */
  31 
  32 import java.applet.Applet;
  33 import java.awt.*;
  34 import java.awt.event.*;
  35 import java.util.concurrent.atomic.AtomicInteger;
  36 
  37 import test.java.awt.regtesthelpers.Util;
  38 
  39 public class MouseClickTest extends Applet
  40 {
  41     private static final int TIMEOUT = 3000;
  42 
  43     public void init()
  44     {
  45         setLayout (new BorderLayout ());
  46     }
  47 
  48     public void start ()
  49     {
  50         setSize (200,200);
  51         setVisible(true);
  52         validate();
  53 
  54         runTests();
  55     }
  56 
  57     public static final void main(String args[])
  58     {
  59         MouseClickTest test = new MouseClickTest();
  60         test.init();
  61         test.start();
  62     }
  63 
  64     void runTests()
  65     {
  66         Frame frame = new Frame("frame");
  67         frame.setBounds(100, 100, 100, 100);
  68         frame.setVisible(true);
  69         frame.validate();
  70         Util.waitTillShown(frame);
  71 
  72         Robot robot = Util.createRobot();
  73         robot.setAutoDelay(10);
  74 
  75         oneButtonPressRelease(frame, robot, false, 1);
  76         oneButtonPressRelease(frame, robot, true, 0);
  77         twoButtonPressRelease(frame, robot, false, 2);
  78         twoButtonPressRelease(frame, robot, true, 1);
  79     }
  80 
  81     /*
  82      * The function tests that the MOUSE_CLICKED event is triggered
  83      * when the robot just makes one button click. Also it verifies that
  84      * no event is coming when dragging happens until button will be
  85      * relealed.
  86      */
  87     public static void oneButtonPressRelease(final Component comp, final Robot robot,
  88                                              final boolean dragging, final int EXPECTED_EVENT_COUNT)
  89     {
  90         final AtomicInteger eventCount = new AtomicInteger(0);
  91         final MouseAdapter adapter = new MouseEventAdapter(eventCount, EXPECTED_EVENT_COUNT);
  92         comp.addMouseListener(adapter);
  93 
  94         Rectangle bounds = new Rectangle(comp.getLocationOnScreen(), comp.getSize());
  95 
  96         robot.mouseMove(bounds.x + bounds.width / 4, bounds.y + bounds.height / 2);
  97         robot.mousePress(InputEvent.BUTTON1_MASK);
  98         if (dragging) {
  99             robot.mouseMove(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
 100         }
 101         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 102 
 103         Util.waitForIdle(robot);
 104         waitForCondition(eventCount, EXPECTED_EVENT_COUNT, TIMEOUT);
 105 
 106         if (eventCount.get() != EXPECTED_EVENT_COUNT) {
 107             System.out.println("Wrong number of MouseClick events were generated: " +
 108                                eventCount.get() + ", expected: " + EXPECTED_EVENT_COUNT);
 109             throw new RuntimeException("Test failed!");
 110         }
 111 
 112         comp.removeMouseListener(adapter);
 113         System.out.println("Test passed.");
 114     }
 115 
 116     /*
 117      * The function tests sending of the MOUSE_CLICKED events when two
 118      * different mouse buttons are used to generate MOUSE_CLICKED event.
 119      * It verifies that number of coming MouseClick events equals to number
 120      * of mouse clicks are performed by the robot.
 121      */
 122     public static void twoButtonPressRelease(final Component comp, final Robot robot,
 123                                              final boolean dragging, final int EXPECTED_EVENT_COUNT)
 124     {
 125         final AtomicInteger eventCount = new AtomicInteger(0);
 126         final MouseAdapter adapter = new MouseEventAdapter(eventCount, EXPECTED_EVENT_COUNT);
 127         comp.addMouseListener(adapter);
 128 
 129         Rectangle bounds = new Rectangle(comp.getLocationOnScreen(), comp.getSize());
 130 
 131         robot.mouseMove(bounds.x + bounds.width / 4, bounds.y + bounds.height / 2);
 132         robot.mousePress(InputEvent.BUTTON1_MASK);
 133         if (dragging) {
 134             robot.mouseMove(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
 135         }
 136         robot.mousePress(InputEvent.BUTTON2_MASK);
 137         robot.mouseRelease(InputEvent.BUTTON2_MASK);
 138         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 139 
 140         Util.waitForIdle(robot);
 141         waitForCondition(eventCount, EXPECTED_EVENT_COUNT, TIMEOUT);
 142 
 143         if (eventCount.get() != EXPECTED_EVENT_COUNT) {
 144             System.out.println("Wrong number of MouseClick events were generated: " +
 145                                eventCount.get() + ", expected: " + EXPECTED_EVENT_COUNT);
 146             throw new RuntimeException("Test failed!");
 147         }
 148 
 149         comp.removeMouseListener(adapter);
 150         System.out.println("Test passed.");
 151     }
 152 
 153     private static void waitForCondition(final AtomicInteger eventCount, int EXPECTED_EVENT_COUNT,
 154                                          long timeout)
 155     {
 156         synchronized (eventCount) {
 157             if (eventCount.get() != EXPECTED_EVENT_COUNT) {
 158                 try {
 159                     eventCount.wait(timeout);
 160                 } catch (InterruptedException e) {
 161                     System.out.println("Interrupted unexpectedly!");
 162                     throw new RuntimeException(e);
 163                 }
 164             }
 165         }
 166     }
 167 }
 168 
 169 class MouseEventAdapter extends MouseAdapter {
 170 
 171     private final int EXPECTED_EVENT_COUNT;
 172     private final AtomicInteger eventCount;
 173 
 174     public MouseEventAdapter(final AtomicInteger eventCount, final int EXPECTED_EVENT_COUNT) {
 175         this.EXPECTED_EVENT_COUNT = EXPECTED_EVENT_COUNT;
 176         this.eventCount = eventCount;
 177     }
 178 
 179     public void mouseClicked(MouseEvent e) {
 180         System.out.println(e);
 181         synchronized (eventCount) {
 182             if (eventCount.incrementAndGet() == EXPECTED_EVENT_COUNT) {
 183                 eventCount.notifyAll();
 184             }
 185         }
 186     }
 187 }