InputVerifierTest2.java revision 14851:980da45565c8
1/*
2 * Copyright (c) 2006, 2016, 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
39import java.awt.AWTException;
40import java.awt.BorderLayout;
41import java.awt.Component;
42import java.awt.Dialog;
43import java.awt.Frame;
44import java.awt.Point;
45import java.awt.Robot;
46import java.awt.TextArea;
47
48import java.awt.event.InputEvent;
49
50import javax.swing.InputVerifier;
51import javax.swing.JButton;
52import javax.swing.JComponent;
53import javax.swing.JFrame;
54import javax.swing.JTextField;
55import javax.swing.JWindow;
56
57public class InputVerifierTest2
58{
59
60    private static void init()
61    {
62        //*** Create instructions for the user here ***
63
64        String[] instructions =
65        {
66            "This is an AUTOMATIC test, simply wait until it is done.",
67            "The result (passed or failed) will be shown in the",
68            "message window below."
69        };
70        Sysout.createDialog( );
71        Sysout.printInstructions( instructions );
72
73        JFrame frame = new JFrame();
74        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
75        JTextField tf = new JTextField(10);
76        frame.getContentPane().add(tf);
77
78        final JWindow w = new JWindow(frame);
79        JButton btn1 = new JButton("window");
80        btn1.setName("bnt1");
81        w.getContentPane().add(btn1);
82        w.pack();
83        w.setVisible(true);
84
85        frame.setSize(200, 200);
86        frame.setVisible(true);
87
88
89        Robot r = null;
90        try {
91            r = new Robot();
92        } catch (AWTException e) {
93            InputVerifierTest2.fail(e);
94        }
95
96
97        try {
98            r.waitForIdle();
99            mouseClickOnComp(r, tf);
100            r.waitForIdle();
101
102            if (!tf.isFocusOwner()) {
103                throw new RuntimeException("t1 is not a focus owner");
104            }
105
106            tf.setInputVerifier(new InputVerifier() {
107                    public boolean verify(JComponent input) {
108                        System.err.println("verify on " + input);
109                        throw new RuntimeException("InputVerifier should not be called");
110                    }
111                });
112            btn1.requestFocus();
113        } catch (Exception e) {
114            InputVerifierTest2.fail(e);
115        }
116
117        InputVerifierTest2.pass();
118
119    }//End  init()
120
121
122    static void mouseClickOnComp(Robot r, Component comp) {
123        Point loc = comp.getLocationOnScreen();
124        loc.x += comp.getWidth() / 2;
125        loc.y += comp.getHeight() / 2;
126        r.mouseMove(loc.x, loc.y);
127        r.delay(10);
128        r.mousePress(InputEvent.BUTTON1_MASK);
129        r.delay(10);
130        r.mouseRelease(InputEvent.BUTTON1_MASK);
131    }
132
133    /*****************************************************
134     * Standard Test Machinery Section
135     * DO NOT modify anything in this section -- it's a
136     * standard chunk of code which has all of the
137     * synchronisation necessary for the test harness.
138     * By keeping it the same in all tests, it is easier
139     * to read and understand someone else's test, as
140     * well as insuring that all tests behave correctly
141     * with the test harness.
142     * There is a section following this for test-
143     * classes
144     ******************************************************/
145    private static boolean theTestPassed = false;
146    private static boolean testGeneratedInterrupt = false;
147    private static String failureMessage = "";
148
149    private static Thread mainThread = null;
150
151    private static int sleepTime = 300000;
152
153    // Not sure about what happens if multiple of this test are
154    //  instantiated in the same VM.  Being static (and using
155    //  static vars), it aint gonna work.  Not worrying about
156    //  it for now.
157    public static void main( String args[] ) throws InterruptedException
158    {
159        mainThread = Thread.currentThread();
160        try
161        {
162            init();
163        }
164        catch( TestPassedException e )
165        {
166            //The test passed, so just return from main and harness will
167            // interepret this return as a pass
168            return;
169        }
170        //At this point, neither test pass nor test fail has been
171        // called -- either would have thrown an exception and ended the
172        // test, so we know we have multiple threads.
173
174        //Test involves other threads, so sleep and wait for them to
175        // called pass() or fail()
176        try
177        {
178            Thread.sleep( sleepTime );
179            //Timed out, so fail the test
180            throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
181        }
182        catch (InterruptedException e)
183        {
184            //The test harness may have interrupted the test.  If so, rethrow the exception
185            // so that the harness gets it and deals with it.
186            if( ! testGeneratedInterrupt ) throw e;
187
188            //reset flag in case hit this code more than once for some reason (just safety)
189            testGeneratedInterrupt = false;
190
191            if ( theTestPassed == false )
192            {
193                throw new RuntimeException( failureMessage );
194            }
195        }
196
197    }//main
198
199    public static synchronized void setTimeoutTo( int seconds )
200    {
201        sleepTime = seconds * 1000;
202    }
203
204    public static synchronized void pass()
205    {
206        Sysout.println( "The test passed." );
207        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
208        //first check if this is executing in main thread
209        if ( mainThread == Thread.currentThread() )
210        {
211            //Still in the main thread, so set the flag just for kicks,
212            // and throw a test passed exception which will be caught
213            // and end the test.
214            theTestPassed = true;
215            throw new TestPassedException();
216        }
217        theTestPassed = true;
218        testGeneratedInterrupt = true;
219        mainThread.interrupt();
220    }//pass()
221
222    public static synchronized void fail( Exception whyFailed )
223    {
224        Sysout.println( "The test failed: " + whyFailed );
225        Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
226        //check if this called from main thread
227        if ( mainThread == Thread.currentThread() )
228        {
229            //If main thread, fail now 'cause not sleeping
230            throw new RuntimeException( whyFailed );
231        }
232        theTestPassed = false;
233        testGeneratedInterrupt = true;
234        failureMessage = whyFailed.toString();
235        mainThread.interrupt();
236    }//fail()
237
238}// class InputVerifierTest2
239
240//This exception is used to exit from any level of call nesting
241// when it's determined that the test has passed, and immediately
242// end the test.
243class TestPassedException extends RuntimeException
244{
245}
246
247//*********** End Standard Test Machinery Section **********
248
249/****************************************************
250 Standard Test Machinery
251 DO NOT modify anything below -- it's a standard
252  chunk of code whose purpose is to make user
253  interaction uniform, and thereby make it simpler
254  to read and understand someone else's test.
255 ****************************************************/
256
257/**
258 This is part of the standard test machinery.
259 It creates a dialog (with the instructions), and is the interface
260  for sending text messages to the user.
261 To print the instructions, send an array of strings to Sysout.createDialog
262  WithInstructions method.  Put one line of instructions per array entry.
263 To display a message for the tester to see, simply call Sysout.println
264  with the string to be displayed.
265 This mimics System.out.println but works within the test harness as well
266  as standalone.
267 */
268
269class Sysout
270{
271    private static TestDialog dialog;
272
273    public static void createDialogWithInstructions( String[] instructions )
274    {
275        dialog = new TestDialog( new Frame(), "Instructions" );
276        dialog.printInstructions( instructions );
277        dialog.setVisible(true);
278        println( "Any messages for the tester will display here." );
279    }
280
281    public static void createDialog( )
282    {
283        dialog = new TestDialog( new Frame(), "Instructions" );
284        String[] defInstr = { "Instructions will appear here. ", "" } ;
285        dialog.printInstructions( defInstr );
286        dialog.setVisible(true);
287        println( "Any messages for the tester will display here." );
288    }
289
290
291    public static void printInstructions( String[] instructions )
292    {
293        dialog.printInstructions( instructions );
294    }
295
296
297    public static void println( String messageIn )
298    {
299        dialog.displayMessage( messageIn );
300        System.out.println(messageIn);
301    }
302
303}// Sysout  class
304
305/**
306  This is part of the standard test machinery.  It provides a place for the
307   test instructions to be displayed, and a place for interactive messages
308   to the user to be displayed.
309  To have the test instructions displayed, see Sysout.
310  To have a message to the user be displayed, see Sysout.
311  Do not call anything in this dialog directly.
312  */
313class TestDialog extends Dialog
314{
315
316    TextArea instructionsText;
317    TextArea messageText;
318    int maxStringLength = 80;
319
320    //DO NOT call this directly, go through Sysout
321    public TestDialog( Frame frame, String name )
322    {
323        super( frame, name );
324        int scrollBoth = TextArea.SCROLLBARS_BOTH;
325        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
326        add( "North", instructionsText );
327
328        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
329        add("Center", messageText);
330
331        pack();
332
333        setVisible(true);
334    }// TestDialog()
335
336    //DO NOT call this directly, go through Sysout
337    public void printInstructions( String[] instructions )
338    {
339        //Clear out any current instructions
340        instructionsText.setText( "" );
341
342        //Go down array of instruction strings
343
344        String printStr, remainingStr;
345        for( int i=0; i < instructions.length; i++ )
346        {
347            //chop up each into pieces maxSringLength long
348            remainingStr = instructions[ i ];
349            while( remainingStr.length() > 0 )
350            {
351                //if longer than max then chop off first max chars to print
352                if( remainingStr.length() >= maxStringLength )
353                {
354                    //Try to chop on a word boundary
355                    int posOfSpace = remainingStr.
356                        lastIndexOf( ' ', maxStringLength - 1 );
357
358                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
359
360                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
361                    remainingStr = remainingStr.substring( posOfSpace + 1 );
362                }
363                //else just print
364                else
365                {
366                    printStr = remainingStr;
367                    remainingStr = "";
368                }
369
370                instructionsText.append( printStr + "\n" );
371
372            }// while
373
374        }// for
375
376    }//printInstructions()
377
378    //DO NOT call this directly, go through Sysout
379    public void displayMessage( String messageIn )
380    {
381        messageText.append( messageIn + "\n" );
382        System.out.println(messageIn);
383    }
384
385}// TestDialog  class
386