1 /* 2 * Copyright (c) 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 package test.renderlock; 27 28 import com.sun.javafx.PlatformUtil; 29 import java.util.concurrent.CountDownLatch; 30 import java.util.concurrent.TimeUnit; 31 import java.util.concurrent.atomic.AtomicReference; 32 import javafx.animation.FillTransition; 33 import javafx.animation.Timeline; 34 import javafx.application.Application; 35 import javafx.application.Platform; 36 import javafx.scene.Group; 37 import javafx.scene.Scene; 38 import javafx.scene.control.Alert; 39 import javafx.scene.control.Button; 40 import javafx.scene.control.ButtonType; 41 import javafx.scene.layout.VBox; 42 import javafx.scene.paint.Color; 43 import javafx.scene.shape.Rectangle; 44 import javafx.stage.Stage; 45 import javafx.util.Duration; 46 import junit.framework.AssertionFailedError; 47 import org.junit.AfterClass; 48 import org.junit.BeforeClass; 49 import test.util.Util; 50 51 import static org.junit.Assert.*; 52 import static org.junit.Assume.*; 53 import static test.util.Util.TIMEOUT; 54 55 /** 56 * Common base class for testing snapshot. 57 */ 58 public class RenderLockCommon { 59 60 // Sleep time showing/hiding window in milliseconds 61 private static final int SLEEP_TIME = 1000; 62 63 // Used to launch the application before running any test 64 private static final CountDownLatch launchLatch = new CountDownLatch(1); 65 66 // Singleton Application instance 67 static MyApp myApp; 68 69 // Application class. An instance is created and initialized before running 70 // the first test, and it lives through the execution of all tests. 71 public static class MyApp extends Application { 72 Stage primaryStage; 73 74 @Override public void init() { 75 RenderLockCommon.myApp = this; 76 } 77 78 @Override public void start(Stage primaryStage) throws Exception { 79 assertTrue(Platform.isFxApplicationThread()); 80 primaryStage.setTitle("Primary stage"); 81 Rectangle rect = new Rectangle(100, 50); 82 FillTransition trans = new FillTransition(Duration.millis(500), 83 rect, Color.BLUE, Color.VIOLET); 84 trans.setCycleCount(Timeline.INDEFINITE); 85 trans.setAutoReverse(true); 86 trans.play(); 87 Group root = new Group(rect); 88 Scene scene = new Scene(root); 89 scene.setFill(Color.LIGHTYELLOW); 90 primaryStage.setScene(scene); 91 primaryStage.setX(0); 92 primaryStage.setY(0); 93 primaryStage.setWidth(210); 94 primaryStage.setHeight(180); 95 assertFalse(primaryStage.isShowing()); 96 primaryStage.show(); 97 assertTrue(primaryStage.isShowing()); 98 99 this.primaryStage = primaryStage; 100 launchLatch.countDown(); 101 } 102 } 103 104 @BeforeClass 105 public static void doSetupOnce() throws Exception { 106 // These tests are only valid on Windows and Mac. 107 // On Linux the closing of the window does not trigger a 108 // focusLost event with the lock held 109 assumeTrue(PlatformUtil.isMac() || PlatformUtil.isWindows()); 110 111 // Start the Application 112 new Thread(() -> Application.launch(MyApp.class, (String[])null)).start(); 113 114 if (!launchLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { 115 fail("Timeout waiting for Application to launch"); 116 } 117 118 assertEquals(0, launchLatch.getCount()); 119 } 120 121 @AfterClass 122 public static void doTeardownOnce() { 123 Platform.exit(); 124 } 125 126 // ========================== TEST CASES ========================== 127 128 private Stage testStage; 129 130 protected void doWindowCloseTest() throws Exception { 131 final CountDownLatch alertDoneLatch = new CountDownLatch(1); 132 final AtomicReference<ButtonType> alertResult = new AtomicReference<>(); 133 134 Util.runAndWait(() -> { 135 Button button1 = new Button("The Button"); 136 button1.focusedProperty().addListener((obs, oldValue, newValue) -> { 137 if (!newValue) { 138 //System.err.println("lost focus"); 139 final Alert alert = new Alert(Alert.AlertType.CONFIRMATION); 140 Thread t = new Thread(() -> { 141 Util.sleep(SLEEP_TIME); 142 //System.err.println("scheduling runLater to hide alert"); 143 Platform.runLater(() -> { 144 //System.err.println("Calling alert.hide"); 145 alert.hide(); 146 }); 147 }); 148 t.start(); 149 ButtonType result = alert.showAndWait().get(); 150 alertResult.set(result); 151 alertDoneLatch.countDown(); 152 //System.err.println("result = " + result); 153 //System.err.println("focus listener exit"); 154 } 155 }); 156 157 Button button2 = new Button("Other Button"); 158 159 testStage = new Stage(); 160 testStage.setScene(new Scene(new VBox(button1, button2), 400, 300)); 161 button1.requestFocus(); 162 testStage.requestFocus(); 163 testStage.show(); 164 }); 165 166 Util.sleep(SLEEP_TIME); 167 //System.err.println("scheduling runLater to hide otherStage"); 168 Platform.runLater(() -> { 169 //System.err.println("Calling otherStage.hide"); 170 testStage.hide(); 171 }); 172 173 // Wait for results 174 if (!alertDoneLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { 175 fail("Timeout waiting for alert to be hidden"); 176 } 177 178 assertSame(ButtonType.CANCEL, alertResult.get()); 179 } 180 181 }