1 /* 2 * Copyright (c) 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. 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.javafx.stage; 27 28 import java.util.TimerTask; 29 import java.util.Timer; 30 import java.util.concurrent.CountDownLatch; 31 import java.util.concurrent.TimeUnit; 32 33 import javafx.application.Application; 34 import javafx.application.Platform; 35 import javafx.beans.value.ChangeListener; 36 import javafx.beans.value.ObservableValue; 37 import javafx.geometry.Rectangle2D; 38 import javafx.scene.Scene; 39 import javafx.scene.control.Label; 40 import javafx.stage.Screen; 41 import javafx.stage.Stage; 42 43 import javafx.stage.Window; 44 import org.junit.BeforeClass; 45 import org.junit.Test; 46 47 import static junit.framework.Assert.assertTrue; 48 import static org.junit.Assert.fail; 49 50 public class ChildStageLocationTest { 51 static CountDownLatch startupLatch; 52 static Timer timer; 53 static Runnable runNext; 54 static volatile Stage stage; 55 static volatile Stage childStage; 56 static double x, y; 57 58 public static void main(String[] args) { 59 initFX(); 60 new ChildStageLocationTest().testLocation(); 61 } 62 63 @BeforeClass 64 public static void initFX() { 65 startupLatch = new CountDownLatch(1); 66 new Thread(() -> Application.launch(TestApp.class, (String[])null)).start(); 67 try { 68 if (!startupLatch.await(15, TimeUnit.SECONDS)) { 69 fail("Timeout waiting for FX runtime to start"); 70 } 71 } catch (InterruptedException ex) { 72 fail("Unexpected exception: " + ex); 73 } 74 } 75 76 @Test 77 public void testLocation() { 78 Rectangle2D bounds = Screen.getPrimary().getVisualBounds(); 79 Window window = stage.getScene().getWindow(); 80 double minX = bounds.getMinX() + (bounds.getWidth() - window.getWidth())/2 - 50; 81 double minY = bounds.getMinY() + (bounds.getHeight() - window.getHeight())/3 - 100; 82 System.out.println("Primary stage location: " + stage.getX() + " " + stage.getY()); 83 assertTrue("Primary stage X location should be >" + minX, stage.getX() > minX); 84 assertTrue("Primary stage Y location should be >" + minY, stage.getY() > minY); 85 86 window = childStage.getScene().getWindow(); 87 minX = bounds.getMinX() + (bounds.getWidth() - window.getWidth())/2 - 50; 88 minY = bounds.getMinY() + (bounds.getHeight() - window.getHeight())/3 - 100; 89 System.out.println("Child stage location: " + childStage.getX() + " " + childStage.getY()); 90 assertTrue("Child stage X location should be >" + minX, childStage.getX() > minX); 91 assertTrue("Child stage Y location should be >" + minY, childStage.getY() > minY); 92 } 93 94 public static class TestApp extends Application implements ChangeListener { 95 96 @Override 97 public void start(Stage stage) throws Exception { 98 stage.setScene(new Scene(new Label("Label"))); 99 stage.xProperty().addListener(this); 100 stage.yProperty().addListener(this); 101 stage.widthProperty().addListener(this); 102 stage.heightProperty().addListener(this); 103 ChildStageLocationTest.stage = stage; 104 runNext = () -> { 105 runNext = () -> {}; 106 Platform.runLater(this::createChildStage); 107 }; 108 stage.show(); 109 } 110 111 @Override 112 public void changed(ObservableValue observable, Object oldValue, Object newValue) { 113 if (timer != null) { 114 timer.cancel(); 115 } 116 timer = new Timer(); 117 timer.schedule(new TimerTask() { 118 @Override 119 public void run() { 120 runNext.run(); 121 } 122 }, 1500); 123 } 124 125 void createChildStage() { 126 childStage = new Stage(); 127 childStage.setScene(new Scene(new Label("Label"))); 128 childStage.sizeToScene(); 129 childStage.xProperty().addListener(this); 130 childStage.yProperty().addListener(this); 131 childStage.widthProperty().addListener(this); 132 childStage.heightProperty().addListener(this); 133 runNext = startupLatch::countDown; 134 childStage.showAndWait(); 135 } 136 } 137 138 } 139