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 6378278
  28   @summary Apparent missing key events causing Bugster to break
  29   @author oleg.sukhodolsky: area=awt.focus
  30   @run main InputVerifierTest
  31 */
  32 
  33 /**
  34  * InputVerifierTest.java
  35  *
  36  * summary: Apparent missing key events causing Bugster to break
  37  */
  38 
  39 import java.awt.AWTException;
  40 import java.awt.BorderLayout;
  41 import java.awt.Component;
  42 import java.awt.Dialog;
  43 import java.awt.Frame;
  44 import java.awt.Point;
  45 import java.awt.Robot;
  46 import java.awt.TextArea;
  47 
  48 import java.awt.event.InputEvent;
  49 import java.awt.event.KeyEvent;
  50 
  51 import javax.swing.InputVerifier;
  52 import javax.swing.JComponent;
  53 import javax.swing.JFrame;
  54 import javax.swing.JTextField;
  55 
  56 public class InputVerifierTest
  57 {
  58 
  59     //*** test-writer defined static variables go here ***
  60     static volatile boolean ivWasCalled = false;
  61 
  62     private static void init()
  63     {
  64         JFrame frame = new JFrame();
  65         JTextField t1 = new JTextField();
  66         t1.setInputVerifier(new InputVerifier() {
  67             public boolean verify(JComponent input) {
  68                 System.out.println("verify(" + input + ")");
  69                 ivWasCalled = true;
  70                 return true;
  71             }
  72         });
  73         JTextField t2 = new JTextField();
  74 
  75         frame.getContentPane().add(t1, BorderLayout.NORTH);
  76         frame.getContentPane().add(t2, BorderLayout.SOUTH);
  77         frame.setSize(200, 200);
  78         frame.setVisible(true);
  79 
  80         Robot r = null;
  81         try {
  82             r = new Robot();
  83         } catch (AWTException e) {
  84             e.printStackTrace();
  85             InputVerifierTest.fail(e.toString());
  86         }
  87 
  88         try {
  89             r.waitForIdle();
  90 
  91             mouseClickOnComp(r, t1);
  92             r.waitForIdle();
  93 
  94             if (!t1.isFocusOwner()) {
  95                 throw new RuntimeException("t1 is not a focus owner");
  96             }
  97             ivWasCalled = false;
  98             r.keyPress(KeyEvent.VK_TAB);
  99             r.delay(10);
 100             r.keyRelease(KeyEvent.VK_TAB);
 101             r.waitForIdle();
 102 
 103             if (!t2.isFocusOwner()) {
 104                 throw new RuntimeException("t2 is not a focus owner");
 105             }
 106             if (!ivWasCalled) {
 107                 throw new RuntimeException("InputVerifier was not called after tabbing");
 108             }
 109 
 110             mouseClickOnComp(r, t1);
 111             r.waitForIdle();
 112 
 113             if (!t1.isFocusOwner()) {
 114                 throw new RuntimeException("t1 is not a focus owner");
 115             }
 116 
 117             ivWasCalled = false;
 118             mouseClickOnComp(r, t2);
 119             r.waitForIdle();
 120             if (!t2.isFocusOwner()) {
 121                 throw new RuntimeException("t2 is not a focus owner");
 122             }
 123             if (!ivWasCalled) {
 124                 throw new RuntimeException("InputVErifier was not called after mouse press");
 125             }
 126         } catch (Exception e) {
 127             e.printStackTrace();
 128             InputVerifierTest.fail(e.toString());
 129         }
 130 
 131         InputVerifierTest.pass();
 132 
 133     }//End  init()
 134 
 135     static void mouseClickOnComp(Robot r, Component comp) {
 136         Point loc = comp.getLocationOnScreen();
 137         loc.x += comp.getWidth() / 2;
 138         loc.y += comp.getHeight() / 2;
 139         r.mouseMove(loc.x, loc.y);
 140         r.delay(10);
 141         r.mousePress(InputEvent.BUTTON1_MASK);
 142         r.delay(10);
 143         r.mouseRelease(InputEvent.BUTTON1_MASK);
 144     }
 145 
 146     /*****************************************************
 147      * Standard Test Machinery Section
 148      * DO NOT modify anything in this section -- it's a
 149      * standard chunk of code which has all of the
 150      * synchronisation necessary for the test harness.
 151      * By keeping it the same in all tests, it is easier
 152      * to read and understand someone else's test, as
 153      * well as insuring that all tests behave correctly
 154      * with the test harness.
 155      * There is a section following this for test-
 156      * classes
 157      ******************************************************/
 158     private static boolean theTestPassed = false;
 159     private static boolean testGeneratedInterrupt = false;
 160     private static String failureMessage = "";
 161 
 162     private static Thread mainThread = null;
 163 
 164     private static int sleepTime = 300000;
 165 
 166     // Not sure about what happens if multiple of this test are
 167     //  instantiated in the same VM.  Being static (and using
 168     //  static vars), it aint gonna work.  Not worrying about
 169     //  it for now.
 170     public static void main( String args[] ) throws InterruptedException
 171     {
 172         mainThread = Thread.currentThread();
 173         try
 174         {
 175             init();
 176         }
 177         catch( TestPassedException e )
 178         {
 179             //The test passed, so just return from main and harness will
 180             // interepret this return as a pass
 181             return;
 182         }
 183         //At this point, neither test pass nor test fail has been
 184         // called -- either would have thrown an exception and ended the
 185         // test, so we know we have multiple threads.
 186 
 187         //Test involves other threads, so sleep and wait for them to
 188         // called pass() or fail()
 189         try
 190         {
 191             Thread.sleep( sleepTime );
 192             //Timed out, so fail the test
 193             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 194         }
 195         catch (InterruptedException e)
 196         {
 197             //The test harness may have interrupted the test.  If so, rethrow the exception
 198             // so that the harness gets it and deals with it.
 199             if( ! testGeneratedInterrupt ) throw e;
 200 
 201             //reset flag in case hit this code more than once for some reason (just safety)
 202             testGeneratedInterrupt = false;
 203 
 204             if ( theTestPassed == false )
 205             {
 206                 throw new RuntimeException( failureMessage );
 207             }
 208         }
 209 
 210     }//main
 211 
 212     public static synchronized void setTimeoutTo( int seconds )
 213     {
 214         sleepTime = seconds * 1000;
 215     }
 216 
 217     public static synchronized void pass()
 218     {
 219         System.out.println( "The test passed." );
 220         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 221         //first check if this is executing in main thread
 222         if ( mainThread == Thread.currentThread() )
 223         {
 224             //Still in the main thread, so set the flag just for kicks,
 225             // and throw a test passed exception which will be caught
 226             // and end the test.
 227             theTestPassed = true;
 228             throw new TestPassedException();
 229         }
 230         theTestPassed = true;
 231         testGeneratedInterrupt = true;
 232         mainThread.interrupt();
 233     }//pass()
 234 
 235     public static synchronized void fail()
 236     {
 237         //test writer didn't specify why test failed, so give generic
 238         fail( "it just plain failed! :-)" );
 239     }
 240 
 241     public static synchronized void fail( String whyFailed )
 242     {
 243         System.out.println( "The test failed: " + whyFailed );
 244         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 245         //check if this called from main thread
 246         if ( mainThread == Thread.currentThread() )
 247         {
 248             //If main thread, fail now 'cause not sleeping
 249             throw new RuntimeException( whyFailed );
 250         }
 251         theTestPassed = false;
 252         testGeneratedInterrupt = true;
 253         failureMessage = whyFailed;
 254         mainThread.interrupt();
 255     }//fail()
 256 
 257 }// class InputVerifierTest
 258 
 259 //This exception is used to exit from any level of call nesting
 260 // when it's determined that the test has passed, and immediately
 261 // end the test.
 262 class TestPassedException extends RuntimeException
 263 {
 264 }