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