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