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