1 /*
   2  * Copyright (c) 2006, 2018, 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 4453162
  28   @summary MouseAdapter should implement MouseMotionListener and MouseWheelListener
  29   @author andrei.dmitriev: area=
  30   @library ../../regtesthelpers
  31   @build Util
  32   @run main MouseAdapterUnitTest
  33 */
  34 
  35 import java.awt.*;
  36 import java.awt.event.*;
  37 import test.java.awt.regtesthelpers.Util;
  38 
  39 public class MouseAdapterUnitTest
  40 {
  41     static Point pt;
  42     static Frame frame = new Frame("Test Frame");
  43     static Button b = new Button("Test Button");
  44     static Robot robot;
  45     static boolean clicked = false;
  46     static boolean pressed = false;
  47     static boolean released = false;
  48     static boolean entered = false;
  49     static boolean exited = false;
  50     static boolean rotated = false;
  51     static boolean dragged = false;
  52     static boolean moved = false;
  53 
  54     private static void init()
  55     {
  56         MouseAdapter ma = new MouseAdapter(){
  57                 public void mouseClicked(MouseEvent e) {clicked = true;}
  58 
  59                 public void mousePressed(MouseEvent e) { pressed = true;}
  60 
  61                 public void mouseReleased(MouseEvent e) {released = true;}
  62 
  63                 public void mouseEntered(MouseEvent e) { entered = true;}
  64 
  65                 public void mouseExited(MouseEvent e) {exited  = true;}
  66 
  67                 public void mouseWheelMoved(MouseWheelEvent e){rotated = true;}
  68 
  69                 public void mouseDragged(MouseEvent e){dragged = true;}
  70 
  71                 public void mouseMoved(MouseEvent e){moved = true;}
  72 
  73             };
  74 
  75         b.addMouseListener(ma);
  76         b.addMouseWheelListener(ma);
  77         b.addMouseMotionListener(ma);
  78 
  79         frame.add(b);
  80         frame.pack();
  81         frame.setVisible(true);
  82 
  83         try{
  84             robot = new Robot();
  85             robot.setAutoWaitForIdle(true);
  86             robot.setAutoDelay(50);
  87 
  88             Util.waitForIdle(robot);
  89 
  90             pt = b.getLocationOnScreen();
  91             testPressMouseButton(InputEvent.BUTTON1_MASK);
  92             testDragMouseButton(InputEvent.BUTTON1_MASK);
  93             testMoveMouseButton();
  94             testCrossingMouseButton();
  95             testWheelMouseButton();
  96         } catch (Throwable e) {
  97             throw new RuntimeException("Test failed. Exception thrown: "+e);
  98         }
  99 
 100         MouseAdapterUnitTest.pass();
 101 
 102     }//End  init()
 103 
 104     public static void testPressMouseButton(int button){
 105         robot.mouseMove(pt.x + b.getWidth()/2, pt.y + b.getHeight()/2);
 106         robot.delay(100);
 107         robot.mousePress(button);
 108         robot.mouseRelease(button);
 109         robot.delay(300);
 110 
 111 
 112         if ( !pressed || !released || !clicked ){
 113             dumpListenerState();
 114             fail("press, release or click hasn't come");
 115         }
 116     }
 117 
 118     public static void testWheelMouseButton(){
 119         robot.mouseMove(pt.x + b.getWidth()/2, pt.y + b.getHeight()/2);
 120         robot.mouseWheel(10);
 121         if ( !rotated){
 122             dumpListenerState();
 123             fail("Wheel event hasn't come");
 124         }
 125     }
 126 
 127     public static void testDragMouseButton(int button) {
 128         robot.mouseMove(pt.x + b.getWidth()/2, pt.y + b.getHeight()/2);
 129         robot.mousePress(button);
 130         moveMouse(pt.x + b.getWidth()/2, pt.y +
 131                   b.getHeight()/2,
 132                   pt.x + b.getWidth()/2,
 133                   pt.y + 2 * b.getHeight());
 134         robot.mouseRelease(button);
 135 
 136         if ( !dragged){
 137             dumpListenerState();
 138             fail("dragged hasn't come");
 139         }
 140 
 141     }
 142 
 143     public static void testMoveMouseButton() {
 144         moveMouse(pt.x + b.getWidth()/2, pt.y +
 145                   b.getHeight()/2,
 146                   pt.x + b.getWidth()/2,
 147                   pt.y + 2 * b.getHeight());
 148 
 149         if ( !moved){
 150             dumpListenerState();
 151             fail("dragged hasn't come");
 152         }
 153 
 154     }
 155 
 156     public static void moveMouse(int x0, int y0, int x1, int y1){
 157         int curX = x0;
 158         int curY = y0;
 159         int dx = x0 < x1 ? 1 : -1;
 160         int dy = y0 < y1 ? 1 : -1;
 161 
 162         while (curX != x1){
 163             curX += dx;
 164             robot.mouseMove(curX, curY);
 165         }
 166         while (curY != y1 ){
 167             curY += dy;
 168             robot.mouseMove(curX, curY);
 169         }
 170     }
 171 
 172     public static void testCrossingMouseButton() {
 173         //exit
 174         moveMouse(pt.x + b.getWidth()/2,
 175                   pt.y + b.getHeight()/2,
 176                   pt.x + b.getWidth()/2,
 177                   pt.y + 2 * b.getHeight());
 178         //enter
 179         moveMouse(pt.x + b.getWidth()/2,
 180                   pt.y + 2 * b.getHeight()/2,
 181                   pt.x + b.getWidth()/2,
 182                   pt.y + b.getHeight());
 183 
 184         if ( !entered || !exited){
 185             dumpListenerState();
 186             fail("enter or exit hasn't come");
 187         }
 188 
 189     }
 190 
 191     public static void dumpListenerState(){
 192         System.out.println("pressed = "+pressed);
 193         System.out.println("released = "+released);
 194         System.out.println("clicked = "+clicked);
 195         System.out.println("entered = "+exited);
 196         System.out.println("rotated = "+rotated);
 197         System.out.println("dragged = "+dragged);
 198         System.out.println("moved = "+moved);
 199     }
 200 
 201     /*****************************************************
 202      * Standard Test Machinery Section
 203      * DO NOT modify anything in this section -- it's a
 204      * standard chunk of code which has all of the
 205      * synchronisation necessary for the test harness.
 206      * By keeping it the same in all tests, it is easier
 207      * to read and understand someone else's test, as
 208      * well as insuring that all tests behave correctly
 209      * with the test harness.
 210      * There is a section following this for test-
 211      * classes
 212      ******************************************************/
 213     private static boolean theTestPassed = false;
 214     private static boolean testGeneratedInterrupt = false;
 215     private static String failureMessage = "";
 216 
 217     private static Thread mainThread = null;
 218 
 219     private static int sleepTime = 300000;
 220 
 221     // Not sure about what happens if multiple of this test are
 222     //  instantiated in the same VM.  Being static (and using
 223     //  static vars), it aint gonna work.  Not worrying about
 224     //  it for now.
 225     public static void main( String args[] ) throws InterruptedException
 226     {
 227         mainThread = Thread.currentThread();
 228         try
 229         {
 230             init();
 231         }
 232         catch( TestPassedException e )
 233         {
 234             //The test passed, so just return from main and harness will
 235             // interepret this return as a pass
 236             return;
 237         }
 238         //At this point, neither test pass nor test fail has been
 239         // called -- either would have thrown an exception and ended the
 240         // test, so we know we have multiple threads.
 241 
 242         //Test involves other threads, so sleep and wait for them to
 243         // called pass() or fail()
 244         try
 245         {
 246             Thread.sleep( sleepTime );
 247             //Timed out, so fail the test
 248             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 249         }
 250         catch (InterruptedException e)
 251         {
 252             //The test harness may have interrupted the test.  If so, rethrow the exception
 253             // so that the harness gets it and deals with it.
 254             if( ! testGeneratedInterrupt ) throw e;
 255 
 256             //reset flag in case hit this code more than once for some reason (just safety)
 257             testGeneratedInterrupt = false;
 258 
 259             if ( theTestPassed == false )
 260             {
 261                 throw new RuntimeException( failureMessage );
 262             }
 263         }
 264 
 265     }//main
 266 
 267     public static synchronized void setTimeoutTo( int seconds )
 268     {
 269         sleepTime = seconds * 1000;
 270     }
 271 
 272     public static synchronized void pass()
 273     {
 274         System.out.println( "The test passed." );
 275         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 276         //first check if this is executing in main thread
 277         if ( mainThread == Thread.currentThread() )
 278         {
 279             //Still in the main thread, so set the flag just for kicks,
 280             // and throw a test passed exception which will be caught
 281             // and end the test.
 282             theTestPassed = true;
 283             throw new TestPassedException();
 284         }
 285         theTestPassed = true;
 286         testGeneratedInterrupt = true;
 287         mainThread.interrupt();
 288     }//pass()
 289 
 290     public static synchronized void fail()
 291     {
 292         //test writer didn't specify why test failed, so give generic
 293         fail( "it just plain failed! :-)" );
 294     }
 295 
 296     public static synchronized void fail( String whyFailed )
 297     {
 298         System.out.println( "The test failed: " + whyFailed );
 299         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 300         //check if this called from main thread
 301         if ( mainThread == Thread.currentThread() )
 302         {
 303             //If main thread, fail now 'cause not sleeping
 304             throw new RuntimeException( whyFailed );
 305         }
 306         theTestPassed = false;
 307         testGeneratedInterrupt = true;
 308         failureMessage = whyFailed;
 309         mainThread.interrupt();
 310     }//fail()
 311 
 312 }// class MouseAdapterUnitTest
 313 
 314 //This exception is used to exit from any level of call nesting
 315 // when it's determined that the test has passed, and immediately
 316 // end the test.
 317 class TestPassedException extends RuntimeException
 318 {
 319 }