1 /*
   2  * Copyright (c) 2006, 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 4453162
  27   @summary MouseAdapter should implement MouseMotionListener and MouseWheelListener
  28   @author andrei.dmitriev: area=
  29   @library ../../regtesthelpers
  30   @build Util
  31   @run main MouseAdapterUnitTest
  32 */
  33 
  34 import java.awt.*;
  35 import java.awt.event.*;
  36 import test.java.awt.regtesthelpers.Util;
  37 
  38 public class MouseAdapterUnitTest
  39 {
  40     static Point pt;
  41     static Frame frame = new Frame("Test Frame");
  42     static Button b = new Button("Test Button");
  43     static Robot robot;
  44     static boolean clicked = false;
  45     static boolean pressed = false;
  46     static boolean released = false;
  47     static boolean entered = false;
  48     static boolean exited = false;
  49     static boolean rotated = false;
  50     static boolean dragged = false;
  51     static boolean moved = false;
  52 
  53     private static void init()
  54     {
  55         String[] instructions =
  56         {
  57             "This is an AUTOMATIC test, simply wait until it is done.",
  58             "The result (passed or failed) will be shown in the",
  59             "message window below."
  60         };
  61         Sysout.createDialog( );
  62         Sysout.printInstructions( instructions );
  63 
  64         MouseAdapter ma = new MouseAdapter(){
  65                 public void mouseClicked(MouseEvent e) {clicked = true;}
  66 
  67                 public void mousePressed(MouseEvent e) { pressed = true;}
  68 
  69                 public void mouseReleased(MouseEvent e) {released = true;}
  70 
  71                 public void mouseEntered(MouseEvent e) { entered = true;}
  72 
  73                 public void mouseExited(MouseEvent e) {exited  = true;}
  74 
  75                 public void mouseWheelMoved(MouseWheelEvent e){rotated = true;}
  76 
  77                 public void mouseDragged(MouseEvent e){dragged = true;}
  78 
  79                 public void mouseMoved(MouseEvent e){moved = true;}
  80 
  81             };
  82 
  83         b.addMouseListener(ma);
  84         b.addMouseWheelListener(ma);
  85         b.addMouseMotionListener(ma);
  86 
  87         frame.add(b);
  88         frame.pack();
  89         frame.setVisible(true);
  90 
  91         try{
  92             robot = new Robot();
  93             robot.setAutoWaitForIdle(true);
  94             robot.setAutoDelay(50);
  95 
  96             Util.waitForIdle(robot);
  97 
  98             pt = b.getLocationOnScreen();
  99             testPressMouseButton(InputEvent.BUTTON1_MASK);
 100             testDragMouseButton(InputEvent.BUTTON1_MASK);
 101             testMoveMouseButton();
 102             testCrossingMouseButton();
 103             testWheelMouseButton();
 104         } catch (Throwable e) {
 105             throw new RuntimeException("Test failed. Exception thrown: "+e);
 106         }
 107 
 108         MouseAdapterUnitTest.pass();
 109 
 110     }//End  init()
 111 
 112     public static void testPressMouseButton(int button){
 113         robot.mouseMove(pt.x + b.getWidth()/2, pt.y + b.getHeight()/2);
 114         robot.delay(100);
 115         robot.mousePress(button);
 116         robot.mouseRelease(button);
 117         robot.delay(300);
 118 
 119 
 120         if ( !pressed || !released || !clicked ){
 121             dumpListenerState();
 122             fail("press, release or click hasn't come");
 123         }
 124     }
 125 
 126     public static void testWheelMouseButton(){
 127         robot.mouseMove(pt.x + b.getWidth()/2, pt.y + b.getHeight()/2);
 128         robot.mouseWheel(10);
 129         if ( !rotated){
 130             dumpListenerState();
 131             fail("Wheel event hasn't come");
 132         }
 133     }
 134 
 135     public static void testDragMouseButton(int button) {
 136         robot.mouseMove(pt.x + b.getWidth()/2, pt.y + b.getHeight()/2);
 137         robot.mousePress(button);
 138         moveMouse(pt.x + b.getWidth()/2, pt.y +
 139                   b.getHeight()/2,
 140                   pt.x + b.getWidth()/2,
 141                   pt.y + 2 * b.getHeight());
 142         robot.mouseRelease(button);
 143 
 144         if ( !dragged){
 145             dumpListenerState();
 146             fail("dragged hasn't come");
 147         }
 148 
 149     }
 150 
 151     public static void testMoveMouseButton() {
 152         moveMouse(pt.x + b.getWidth()/2, pt.y +
 153                   b.getHeight()/2,
 154                   pt.x + b.getWidth()/2,
 155                   pt.y + 2 * b.getHeight());
 156 
 157         if ( !moved){
 158             dumpListenerState();
 159             fail("dragged hasn't come");
 160         }
 161 
 162     }
 163 
 164     public static void moveMouse(int x0, int y0, int x1, int y1){
 165         int curX = x0;
 166         int curY = y0;
 167         int dx = x0 < x1 ? 1 : -1;
 168         int dy = y0 < y1 ? 1 : -1;
 169 
 170         while (curX != x1){
 171             curX += dx;
 172             robot.mouseMove(curX, curY);
 173         }
 174         while (curY != y1 ){
 175             curY += dy;
 176             robot.mouseMove(curX, curY);
 177         }
 178     }
 179 
 180     public static void testCrossingMouseButton() {
 181         //exit
 182         moveMouse(pt.x + b.getWidth()/2,
 183                   pt.y + b.getHeight()/2,
 184                   pt.x + b.getWidth()/2,
 185                   pt.y + 2 * b.getHeight());
 186         //enter
 187         moveMouse(pt.x + b.getWidth()/2,
 188                   pt.y + 2 * b.getHeight()/2,
 189                   pt.x + b.getWidth()/2,
 190                   pt.y + b.getHeight());
 191 
 192         if ( !entered || !exited){
 193             dumpListenerState();
 194             fail("enter or exit hasn't come");
 195         }
 196 
 197     }
 198 
 199     public static void dumpListenerState(){
 200         System.out.println("pressed = "+pressed);
 201         System.out.println("released = "+released);
 202         System.out.println("clicked = "+clicked);
 203         System.out.println("entered = "+exited);
 204         System.out.println("rotated = "+rotated);
 205         System.out.println("dragged = "+dragged);
 206         System.out.println("moved = "+moved);
 207     }
 208 
 209     /*****************************************************
 210      * Standard Test Machinery Section
 211      * DO NOT modify anything in this section -- it's a
 212      * standard chunk of code which has all of the
 213      * synchronisation necessary for the test harness.
 214      * By keeping it the same in all tests, it is easier
 215      * to read and understand someone else's test, as
 216      * well as insuring that all tests behave correctly
 217      * with the test harness.
 218      * There is a section following this for test-
 219      * classes
 220      ******************************************************/
 221     private static boolean theTestPassed = false;
 222     private static boolean testGeneratedInterrupt = false;
 223     private static String failureMessage = "";
 224 
 225     private static Thread mainThread = null;
 226 
 227     private static int sleepTime = 300000;
 228 
 229     // Not sure about what happens if multiple of this test are
 230     //  instantiated in the same VM.  Being static (and using
 231     //  static vars), it aint gonna work.  Not worrying about
 232     //  it for now.
 233     public static void main( String args[] ) throws InterruptedException
 234     {
 235         mainThread = Thread.currentThread();
 236         try
 237         {
 238             init();
 239         }
 240         catch( TestPassedException e )
 241         {
 242             //The test passed, so just return from main and harness will
 243             // interepret this return as a pass
 244             return;
 245         }
 246         //At this point, neither test pass nor test fail has been
 247         // called -- either would have thrown an exception and ended the
 248         // test, so we know we have multiple threads.
 249 
 250         //Test involves other threads, so sleep and wait for them to
 251         // called pass() or fail()
 252         try
 253         {
 254             Thread.sleep( sleepTime );
 255             //Timed out, so fail the test
 256             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 257         }
 258         catch (InterruptedException e)
 259         {
 260             //The test harness may have interrupted the test.  If so, rethrow the exception
 261             // so that the harness gets it and deals with it.
 262             if( ! testGeneratedInterrupt ) throw e;
 263 
 264             //reset flag in case hit this code more than once for some reason (just safety)
 265             testGeneratedInterrupt = false;
 266 
 267             if ( theTestPassed == false )
 268             {
 269                 throw new RuntimeException( failureMessage );
 270             }
 271         }
 272 
 273     }//main
 274 
 275     public static synchronized void setTimeoutTo( int seconds )
 276     {
 277         sleepTime = seconds * 1000;
 278     }
 279 
 280     public static synchronized void pass()
 281     {
 282         Sysout.println( "The test passed." );
 283         Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
 284         //first check if this is executing in main thread
 285         if ( mainThread == Thread.currentThread() )
 286         {
 287             //Still in the main thread, so set the flag just for kicks,
 288             // and throw a test passed exception which will be caught
 289             // and end the test.
 290             theTestPassed = true;
 291             throw new TestPassedException();
 292         }
 293         theTestPassed = true;
 294         testGeneratedInterrupt = true;
 295         mainThread.interrupt();
 296     }//pass()
 297 
 298     public static synchronized void fail()
 299     {
 300         //test writer didn't specify why test failed, so give generic
 301         fail( "it just plain failed! :-)" );
 302     }
 303 
 304     public static synchronized void fail( String whyFailed )
 305     {
 306         Sysout.println( "The test failed: " + whyFailed );
 307         Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
 308         //check if this called from main thread
 309         if ( mainThread == Thread.currentThread() )
 310         {
 311             //If main thread, fail now 'cause not sleeping
 312             throw new RuntimeException( whyFailed );
 313         }
 314         theTestPassed = false;
 315         testGeneratedInterrupt = true;
 316         failureMessage = whyFailed;
 317         mainThread.interrupt();
 318     }//fail()
 319 
 320 }// class MouseAdapterUnitTest
 321 
 322 //This exception is used to exit from any level of call nesting
 323 // when it's determined that the test has passed, and immediately
 324 // end the test.
 325 class TestPassedException extends RuntimeException
 326 {
 327 }
 328 
 329 //*********** End Standard Test Machinery Section **********
 330 
 331 
 332 //************ Begin classes defined for the test ****************
 333 
 334 // if want to make listeners, here is the recommended place for them, then instantiate
 335 //  them in init()
 336 
 337 /* Example of a class which may be written as part of a test
 338 class NewClass implements anInterface
 339  {
 340    static int newVar = 0;
 341 
 342    public void eventDispatched(AWTEvent e)
 343     {
 344       //Counting events to see if we get enough
 345       eventCount++;
 346 
 347       if( eventCount == 20 )
 348        {
 349          //got enough events, so pass
 350 
 351          MouseAdapterUnitTest.pass();
 352        }
 353       else if( tries == 20 )
 354        {
 355          //tried too many times without getting enough events so fail
 356 
 357          MouseAdapterUnitTest.fail();
 358        }
 359 
 360     }// eventDispatched()
 361 
 362  }// NewClass class
 363 
 364 */
 365 
 366 
 367 //************** End classes defined for the test *******************
 368 
 369 
 370 
 371 
 372 /****************************************************
 373  Standard Test Machinery
 374  DO NOT modify anything below -- it's a standard
 375   chunk of code whose purpose is to make user
 376   interaction uniform, and thereby make it simpler
 377   to read and understand someone else's test.
 378  ****************************************************/
 379 
 380 /**
 381  This is part of the standard test machinery.
 382  It creates a dialog (with the instructions), and is the interface
 383   for sending text messages to the user.
 384  To print the instructions, send an array of strings to Sysout.createDialog
 385   WithInstructions method.  Put one line of instructions per array entry.
 386  To display a message for the tester to see, simply call Sysout.println
 387   with the string to be displayed.
 388  This mimics System.out.println but works within the test harness as well
 389   as standalone.
 390  */
 391 
 392 class Sysout
 393 {
 394     private static TestDialog dialog;
 395 
 396     public static void createDialogWithInstructions( String[] instructions )
 397     {
 398         dialog = new TestDialog( new Frame(), "Instructions" );
 399         dialog.printInstructions( instructions );
 400         dialog.setVisible(true);
 401         println( "Any messages for the tester will display here." );
 402     }
 403 
 404     public static void createDialog( )
 405     {
 406         dialog = new TestDialog( new Frame(), "Instructions" );
 407         String[] defInstr = { "Instructions will appear here. ", "" } ;
 408         dialog.printInstructions( defInstr );
 409         dialog.setVisible(true);
 410         println( "Any messages for the tester will display here." );
 411     }
 412 
 413 
 414     public static void printInstructions( String[] instructions )
 415     {
 416         dialog.printInstructions( instructions );
 417     }
 418 
 419 
 420     public static void println( String messageIn )
 421     {
 422         dialog.displayMessage( messageIn );
 423         System.out.println(messageIn);
 424     }
 425 
 426 }// Sysout  class
 427 
 428 /**
 429   This is part of the standard test machinery.  It provides a place for the
 430    test instructions to be displayed, and a place for interactive messages
 431    to the user to be displayed.
 432   To have the test instructions displayed, see Sysout.
 433   To have a message to the user be displayed, see Sysout.
 434   Do not call anything in this dialog directly.
 435   */
 436 class TestDialog extends Dialog
 437 {
 438 
 439     TextArea instructionsText;
 440     TextArea messageText;
 441     int maxStringLength = 80;
 442 
 443     //DO NOT call this directly, go through Sysout
 444     public TestDialog( Frame frame, String name )
 445     {
 446         super( frame, name );
 447         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 448         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 449         add( "North", instructionsText );
 450 
 451         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 452         add("Center", messageText);
 453 
 454         pack();
 455 
 456         setVisible(true);
 457     }// TestDialog()
 458 
 459     //DO NOT call this directly, go through Sysout
 460     public void printInstructions( String[] instructions )
 461     {
 462         //Clear out any current instructions
 463         instructionsText.setText( "" );
 464 
 465         //Go down array of instruction strings
 466 
 467         String printStr, remainingStr;
 468         for( int i=0; i < instructions.length; i++ )
 469         {
 470             //chop up each into pieces maxSringLength long
 471             remainingStr = instructions[ i ];
 472             while( remainingStr.length() > 0 )
 473             {
 474                 //if longer than max then chop off first max chars to print
 475                 if( remainingStr.length() >= maxStringLength )
 476                 {
 477                     //Try to chop on a word boundary
 478                     int posOfSpace = remainingStr.
 479                         lastIndexOf( ' ', maxStringLength - 1 );
 480 
 481                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 482 
 483                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
 484                     remainingStr = remainingStr.substring( posOfSpace + 1 );
 485                 }
 486                 //else just print
 487                 else
 488                 {
 489                     printStr = remainingStr;
 490                     remainingStr = "";
 491                 }
 492 
 493                 instructionsText.append( printStr + "\n" );
 494 
 495             }// while
 496 
 497         }// for
 498 
 499     }//printInstructions()
 500 
 501     //DO NOT call this directly, go through Sysout
 502     public void displayMessage( String messageIn )
 503     {
 504         messageText.append( messageIn + "\n" );
 505         System.out.println(messageIn);
 506     }
 507 
 508 }// TestDialog  class