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   @test
  25   @key headful
  26   @bug 6322625
  27   @summary REG:Choice does not trigger MouseReleased when dragging and releasing the mouse outside choice, XAWT
  28   @author andrei.dmitriev area=awt.choice
  29   @run main DragMouseOutAndRelease
  30 */
  31 
  32 import java.awt.*;
  33 import java.awt.event.*;
  34 
  35 public class DragMouseOutAndRelease
  36 {
  37     static Frame frame = new Frame("Test Frame");
  38     static Choice choice1 = new Choice();
  39     static Robot robot;
  40     static Point pt;
  41     static volatile boolean mousePressed = false;
  42     static volatile boolean mouseReleased = false;
  43 
  44     private static void init()
  45     {
  46         frame.setLayout (new FlowLayout ());
  47         for (int i = 1; i<10;i++){
  48             choice1.add("item "+i);
  49         }
  50         frame.add(choice1);
  51 
  52         choice1.addMouseListener(new MouseAdapter() {
  53                 public void mousePressed(MouseEvent me) {
  54                     mousePressed = true;
  55                     System.out.println(me);
  56                 }
  57                 public void mouseReleased(MouseEvent me) {
  58                     mouseReleased = true;
  59                     System.out.println(me);
  60                 }
  61             });
  62 
  63         frame.pack();
  64         frame.setVisible(true);
  65         frame.validate();
  66 
  67         try {
  68             robot = new Robot();
  69             robot.setAutoDelay(50);
  70             robot.waitForIdle();
  71             testMouseDrag();
  72         } catch (Throwable e) {
  73             new RuntimeException("Test failed. Exception thrown: "+e);
  74         }
  75         DragMouseOutAndRelease.pass();
  76     }//End  init()
  77 
  78     public static void testMouseDrag(){
  79         mousePressed = false;
  80         mouseReleased = false;
  81 
  82         pt = choice1.getLocationOnScreen();
  83         robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2);
  84         robot.waitForIdle();
  85         robot.mousePress(InputEvent.BUTTON1_MASK);
  86         robot.waitForIdle();
  87 
  88 
  89         //move mouse outside Choice
  90         robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y - choice1.getHeight());
  91         robot.waitForIdle();
  92         robot.mouseRelease(InputEvent.BUTTON1_MASK);
  93         robot.waitForIdle();
  94 
  95         if (!mousePressed || !mouseReleased)
  96         {
  97             System.out.println("ERROR: "+ mousePressed+","+mouseReleased);
  98             // close the choice
  99             robot.keyPress(KeyEvent.VK_ESCAPE);
 100             robot.keyRelease(KeyEvent.VK_ESCAPE);
 101             robot.waitForIdle();
 102             DragMouseOutAndRelease.fail("Test failed. Choice should generate PRESSED, RELEASED events outside if pressed on Choice ");
 103         } else{
 104             // close the choice
 105             robot.keyPress(KeyEvent.VK_ESCAPE);
 106             robot.keyRelease(KeyEvent.VK_ESCAPE);
 107             robot.waitForIdle();
 108             System.out.println("Choice did generated PRESSED and RELEASED after Drag outside the Choice ");
 109         }
 110     }
 111 
 112 
 113 
 114     /*****************************************************
 115      * Standard Test Machinery Section
 116      * DO NOT modify anything in this section -- it's a
 117      * standard chunk of code which has all of the
 118      * synchronisation necessary for the test harness.
 119      * By keeping it the same in all tests, it is easier
 120      * to read and understand someone else's test, as
 121      * well as insuring that all tests behave correctly
 122      * with the test harness.
 123      * There is a section following this for test-
 124      * classes
 125      ******************************************************/
 126     private static boolean theTestPassed = false;
 127     private static boolean testGeneratedInterrupt = false;
 128     private static String failureMessage = "";
 129 
 130     private static Thread mainThread = null;
 131 
 132     private static int sleepTime = 300000;
 133 
 134     // Not sure about what happens if multiple of this test are
 135     //  instantiated in the same VM.  Being static (and using
 136     //  static vars), it aint gonna work.  Not worrying about
 137     //  it for now.
 138     public static void main( String args[] ) throws InterruptedException
 139     {
 140         mainThread = Thread.currentThread();
 141         try
 142         {
 143             init();
 144         }
 145         catch( TestPassedException e )
 146         {
 147             //The test passed, so just return from main and harness will
 148             // interepret this return as a pass
 149             return;
 150         }
 151         //At this point, neither test pass nor test fail has been
 152         // called -- either would have thrown an exception and ended the
 153         // test, so we know we have multiple threads.
 154 
 155         //Test involves other threads, so sleep and wait for them to
 156         // called pass() or fail()
 157         try
 158         {
 159             Thread.sleep( sleepTime );
 160             //Timed out, so fail the test
 161             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 162         }
 163         catch (InterruptedException e)
 164         {
 165             //The test harness may have interrupted the test.  If so, rethrow the exception
 166             // so that the harness gets it and deals with it.
 167             if( ! testGeneratedInterrupt ) throw e;
 168 
 169             //reset flag in case hit this code more than once for some reason (just safety)
 170             testGeneratedInterrupt = false;
 171 
 172             if ( theTestPassed == false )
 173             {
 174                 throw new RuntimeException( failureMessage );
 175             }
 176         }
 177 
 178     }//main
 179 
 180     public static synchronized void setTimeoutTo( int seconds )
 181     {
 182         sleepTime = seconds * 1000;
 183     }
 184 
 185     public static synchronized void pass()
 186     {
 187         System.out.println( "The test passed." );
 188         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 189         //first check if this is executing in main thread
 190         if ( mainThread == Thread.currentThread() )
 191         {
 192             //Still in the main thread, so set the flag just for kicks,
 193             // and throw a test passed exception which will be caught
 194             // and end the test.
 195             theTestPassed = true;
 196             throw new TestPassedException();
 197         }
 198         theTestPassed = true;
 199         testGeneratedInterrupt = true;
 200         mainThread.interrupt();
 201     }//pass()
 202 
 203     public static synchronized void fail()
 204     {
 205         //test writer didn't specify why test failed, so give generic
 206         fail( "it just plain failed! :-)" );
 207     }
 208 
 209     public static synchronized void fail( String whyFailed )
 210     {
 211         System.out.println( "The test failed: " + whyFailed );
 212         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 213         //check if this called from main thread
 214         if ( mainThread == Thread.currentThread() )
 215         {
 216             //If main thread, fail now 'cause not sleeping
 217             throw new RuntimeException( whyFailed );
 218         }
 219         theTestPassed = false;
 220         testGeneratedInterrupt = true;
 221         failureMessage = whyFailed;
 222         mainThread.interrupt();
 223     }//fail()
 224 
 225 }// class DragMouseOutAndRelease
 226 
 227 //This exception is used to exit from any level of call nesting
 228 // when it's determined that the test has passed, and immediately
 229 // end the test.
 230 class TestPassedException extends RuntimeException
 231 {
 232 }