1 /*
   2  * Copyright (c) 2007, 2018, 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 
  42 import java.awt.*;
  43 import java.awt.event.*;
  44 import java.beans.PropertyVetoException;
  45 import javax.swing.*;
  46 import test.java.awt.regtesthelpers.Util;
  47 
  48 public 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         // We create a JFrame with two JInternalFrame.
  83         // Each JInternalFrame contains a HW Canvas component.
  84         JFrame jframe = new JFrame("mixing test");
  85         JDesktopPane desktop = new JDesktopPane();
  86         jframe.setContentPane(desktop);
  87         JInternalFrame iframe1 = new JInternalFrame("iframe 1");
  88         iframe1.setIconifiable(true);
  89         iframe1.add(new MyCanvas(Color.RED));
  90         iframe1.setBounds(10, 10, 100, 100);
  91         iframe1.setVisible(true);
  92         desktop.add(iframe1);
  93         JInternalFrame iframe2 = new JInternalFrame("iframe 2");
  94         iframe2.setIconifiable(true);
  95         iframe2.add(new MyCanvas(Color.BLUE));
  96         iframe2.setBounds(50, 50, 100, 100);
  97         iframe2.setVisible(true);
  98         desktop.add(iframe2);
  99 
 100         jframe.setSize(300, 300);
 101         jframe.setVisible(true);
 102 
 103         // Wait until everything gets shown
 104         Util.waitForIdle(null);
 105 
 106         // Now cause a couple of z-order changing operations
 107         iframe2.moveToFront();
 108         Util.waitForIdle(null);
 109         iframe1.moveToFront();
 110         Util.waitForIdle(null);
 111         iframe2.moveToFront();
 112 
 113         // Wait until all the operations complete
 114         Util.waitForIdle(null);
 115 
 116         if (isRemoveNotify) {
 117             fail("The removeNotify() was invoked on the HW Canvas");
 118         }
 119         JInternalFrameTest.pass();
 120 
 121     }//End  init()
 122 
 123 
 124 
 125     /*****************************************************
 126      * Standard Test Machinery Section
 127      * DO NOT modify anything in this section -- it's a
 128      * standard chunk of code which has all of the
 129      * synchronisation necessary for the test harness.
 130      * By keeping it the same in all tests, it is easier
 131      * to read and understand someone else's test, as
 132      * well as insuring that all tests behave correctly
 133      * with the test harness.
 134      * There is a section following this for test-
 135      * classes
 136      ******************************************************/
 137     private static boolean theTestPassed = false;
 138     private static boolean testGeneratedInterrupt = false;
 139     private static String failureMessage = "";
 140 
 141     private static Thread mainThread = null;
 142 
 143     private static int sleepTime = 300000;
 144 
 145     // Not sure about what happens if multiple of this test are
 146     //  instantiated in the same VM.  Being static (and using
 147     //  static vars), it aint gonna work.  Not worrying about
 148     //  it for now.
 149     public static void main( String args[] ) throws InterruptedException
 150     {
 151         mainThread = Thread.currentThread();
 152         try
 153         {
 154             init();
 155         }
 156         catch( TestPassedException e )
 157         {
 158             //The test passed, so just return from main and harness will
 159             // interepret this return as a pass
 160             return;
 161         }
 162         //At this point, neither test pass nor test fail has been
 163         // called -- either would have thrown an exception and ended the
 164         // test, so we know we have multiple threads.
 165 
 166         //Test involves other threads, so sleep and wait for them to
 167         // called pass() or fail()
 168         try
 169         {
 170             Thread.sleep( sleepTime );
 171             //Timed out, so fail the test
 172             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 173         }
 174         catch (InterruptedException e)
 175         {
 176             //The test harness may have interrupted the test.  If so, rethrow the exception
 177             // so that the harness gets it and deals with it.
 178             if( ! testGeneratedInterrupt ) throw e;
 179 
 180             //reset flag in case hit this code more than once for some reason (just safety)
 181             testGeneratedInterrupt = false;
 182 
 183             if ( theTestPassed == false )
 184             {
 185                 throw new RuntimeException( failureMessage );
 186             }
 187         }
 188 
 189     }//main
 190 
 191     public static synchronized void setTimeoutTo( int seconds )
 192     {
 193         sleepTime = seconds * 1000;
 194     }
 195 
 196     public static synchronized void pass()
 197     {
 198         System.out.println( "The test passed." );
 199         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 200         //first check if this is executing in main thread
 201         if ( mainThread == Thread.currentThread() )
 202         {
 203             //Still in the main thread, so set the flag just for kicks,
 204             // and throw a test passed exception which will be caught
 205             // and end the test.
 206             theTestPassed = true;
 207             throw new TestPassedException();
 208         }
 209         theTestPassed = true;
 210         testGeneratedInterrupt = true;
 211         mainThread.interrupt();
 212     }//pass()
 213 
 214     public static synchronized void fail()
 215     {
 216         //test writer didn't specify why test failed, so give generic
 217         fail( "it just plain failed! :-)" );
 218     }
 219 
 220     public static synchronized void fail( String whyFailed )
 221     {
 222         System.out.println( "The test failed: " + whyFailed );
 223         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 224         //check if this called from main thread
 225         if ( mainThread == Thread.currentThread() )
 226         {
 227             //If main thread, fail now 'cause not sleeping
 228             throw new RuntimeException( whyFailed );
 229         }
 230         theTestPassed = false;
 231         testGeneratedInterrupt = true;
 232         failureMessage = whyFailed;
 233         mainThread.interrupt();
 234     }//fail()
 235 
 236 }// class JInternalFrameTest
 237 
 238 //This exception is used to exit from any level of call nesting
 239 // when it's determined that the test has passed, and immediately
 240 // end the test.
 241 class TestPassedException extends RuntimeException
 242 {
 243 }