1 /*
   2  * Copyright (c) 2005, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27   @test
  28   @key headful
  29   @bug 6322270
  30   @summary Test for new API introduced in the fix for 6322270: Window.getWindows(),
  31 Window.getOwnerlessWindows() and Frame.getFrames()
  32   @author artem.ananiev: area=awt.toplevel
  33   @run main GetWindowsTest
  34 */
  35 
  36 import java.awt.*;
  37 import java.awt.event.*;
  38 
  39 import java.util.*;
  40 
  41 public class GetWindowsTest
  42 {
  43     private static Vector<Window> frames = new Vector<Window>();
  44     private static Vector<Window> windows = new Vector<Window>();
  45     private static Vector<Window> ownerless = new Vector<Window>();
  46 
  47     private static void init()
  48     {
  49         Frame f1 = new Frame("F1");
  50         f1.setBounds(100, 100, 100, 100);
  51         f1.setVisible(true);
  52         addToWindowsList(f1);
  53 
  54         Dialog d1 = new Dialog(f1, "D1", Dialog.ModalityType.MODELESS);
  55         d1.setBounds(120, 120, 100, 100);
  56         d1.setVisible(true);
  57         addToWindowsList(d1);
  58 
  59         Window w1 = new Window(d1);
  60         w1.setBounds(140, 140, 100, 100);
  61         w1.setVisible(true);
  62         addToWindowsList(w1);
  63 
  64         Frame f2 = new Frame("F2");
  65         f2.setBounds(300, 100, 100, 100);
  66         f2.setVisible(true);
  67         addToWindowsList(f2);
  68 
  69         Window w2 = new Window(f2);
  70         w2.setBounds(320, 120, 100, 100);
  71         w2.setVisible(true);
  72         addToWindowsList(w2);
  73 
  74         Dialog d2 = new Dialog(f2, "D2", Dialog.ModalityType.MODELESS);
  75         d2.setBounds(340, 140, 100, 100);
  76         d2.setVisible(true);
  77         addToWindowsList(d2);
  78 
  79         Dialog d3 = new Dialog((Frame)null, "D3", Dialog.ModalityType.MODELESS);
  80         d3.setBounds(500, 100, 100, 100);
  81         d3.setVisible(true);
  82         addToWindowsList(d3);
  83 
  84         Dialog d4 = new Dialog(d3, "D4", Dialog.ModalityType.MODELESS);
  85         d4.setBounds(520, 120, 100, 100);
  86         d4.setVisible(true);
  87         addToWindowsList(d4);
  88 
  89         Window w3 = new Window((Frame)null);
  90         w3.setBounds(700, 100, 100, 100);
  91         w3.setVisible(true);
  92         addToWindowsList(w3);
  93 
  94         Window w4 = new Window(w3);
  95         w4.setBounds(720, 120, 100, 100);
  96         w4.setVisible(true);
  97         addToWindowsList(w4);
  98 
  99         try {
 100             Robot robot = new Robot();
 101             robot.waitForIdle();
 102         }catch(Exception ex) {
 103             ex.printStackTrace();
 104             throw new Error("Unexpected failure");
 105         }
 106 
 107         Frame[] fl = Frame.getFrames();
 108         Vector<Window> framesToCheck = new Vector<Window>();
 109         for (Frame f : fl)
 110         {
 111             framesToCheck.add(f);
 112         }
 113         checkWindowsList(frames, framesToCheck, "Frame.getFrames()");
 114 
 115         Window[] wl = Window.getWindows();
 116         Vector<Window> windowsToCheck = new Vector<Window>();
 117         for (Window w : wl)
 118         {
 119             windowsToCheck.add(w);
 120         }
 121         checkWindowsList(windows, windowsToCheck, "Window.getWindows()");
 122 
 123         Window[] ol = Window.getOwnerlessWindows();
 124         Vector<Window> ownerlessToCheck = new Vector<Window>();
 125         for (Window o : ol)
 126         {
 127             ownerlessToCheck.add(o);
 128         }
 129         checkWindowsList(ownerless, ownerlessToCheck, "Window.getOwnerlessWindows()");
 130 
 131         GetWindowsTest.pass();
 132     }
 133 
 134     private static void addToWindowsList(Window w)
 135     {
 136         if (w instanceof Frame)
 137         {
 138             frames.add(w);
 139         }
 140         windows.add(w);
 141         if (w.getOwner() == null)
 142         {
 143             ownerless.add(w);
 144         }
 145     }
 146 
 147     private static void checkWindowsList(Vector<Window> wl1, Vector<Window> wl2, String methodName)
 148     {
 149         if ((wl1.size() != wl2.size()) ||
 150             !wl1.containsAll(wl2) ||
 151             !wl2.containsAll(wl1))
 152         {
 153             fail("Test FAILED: method " + methodName + " returns incorrect list of windows");
 154         }
 155     }
 156 
 157 /*****************************************************
 158  * Standard Test Machinery Section
 159  * DO NOT modify anything in this section -- it's a
 160  * standard chunk of code which has all of the
 161  * synchronisation necessary for the test harness.
 162  * By keeping it the same in all tests, it is easier
 163  * to read and understand someone else's test, as
 164  * well as insuring that all tests behave correctly
 165  * with the test harness.
 166  * There is a section following this for test-
 167  * classes
 168  ******************************************************/
 169 
 170     private static boolean theTestPassed = false;
 171     private static boolean testGeneratedInterrupt = false;
 172     private static String failureMessage = "";
 173 
 174     private static Thread mainThread = null;
 175 
 176     private static int sleepTime = 300000;
 177 
 178     // Not sure about what happens if multiple of this test are
 179     //  instantiated in the same VM.  Being static (and using
 180     //  static vars), it aint gonna work.  Not worrying about
 181     //  it for now.
 182     public static void main( String args[] ) throws InterruptedException
 183     {
 184         mainThread = Thread.currentThread();
 185         try
 186         {
 187             init();
 188         }
 189         catch( TestPassedException e )
 190         {
 191             //The test passed, so just return from main and harness will
 192             // interepret this return as a pass
 193             return;
 194         }
 195         //At this point, neither test pass nor test fail has been
 196         // called -- either would have thrown an exception and ended the
 197         // test, so we know we have multiple threads.
 198 
 199         //Test involves other threads, so sleep and wait for them to
 200         // called pass() or fail()
 201         try
 202         {
 203             Thread.sleep( sleepTime );
 204             //Timed out, so fail the test
 205             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 206         }
 207         catch (InterruptedException e)
 208         {
 209             //The test harness may have interrupted the test.  If so, rethrow the exception
 210             // so that the harness gets it and deals with it.
 211             if( ! testGeneratedInterrupt ) throw e;
 212 
 213             //reset flag in case hit this code more than once for some reason (just safety)
 214             testGeneratedInterrupt = false;
 215 
 216             if ( theTestPassed == false )
 217             {
 218                 throw new RuntimeException( failureMessage );
 219             }
 220         }
 221     }
 222 
 223     public static synchronized void setTimeoutTo( int seconds )
 224     {
 225         sleepTime = seconds * 1000;
 226     }
 227 
 228     public static synchronized void pass()
 229     {
 230         //first check if this is executing in main thread
 231         if ( mainThread == Thread.currentThread() )
 232         {
 233             //Still in the main thread, so set the flag just for kicks,
 234             // and throw a test passed exception which will be caught
 235             // and end the test.
 236             theTestPassed = true;
 237             throw new TestPassedException();
 238         }
 239         theTestPassed = true;
 240         testGeneratedInterrupt = true;
 241         mainThread.interrupt();
 242     }
 243 
 244     public static synchronized void fail()
 245     {
 246         //test writer didn't specify why test failed, so give generic
 247         fail( "it just plain failed! :-)" );
 248     }
 249 
 250     public static synchronized void fail( String whyFailed )
 251     {
 252         //check if this called from main thread
 253         if ( mainThread == Thread.currentThread() )
 254         {
 255             //If main thread, fail now 'cause not sleeping
 256             throw new RuntimeException( whyFailed );
 257         }
 258         theTestPassed = false;
 259         testGeneratedInterrupt = true;
 260         failureMessage = whyFailed;
 261         mainThread.interrupt();
 262     }
 263 }
 264 
 265 //This exception is used to exit from any level of call nesting
 266 // when it's determined that the test has passed, and immediately
 267 // end the test.
 268 class TestPassedException extends RuntimeException
 269 {
 270 }
 271 
 272 //*********** End Standard Test Machinery Section **********