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