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