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