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 javafx.stage;
27
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.HashSet;
31 import java.util.concurrent.CountDownLatch;
32 import java.util.concurrent.TimeUnit;
33 import java.util.concurrent.atomic.AtomicBoolean;
34 import java.util.concurrent.atomic.AtomicReference;
35 import javafx.animation.KeyFrame;
36 import javafx.animation.Timeline;
37 import javafx.application.Application;
38 import javafx.application.Platform;
39 import javafx.print.PrinterJob;
40 import javafx.scene.Group;
41 import javafx.scene.Scene;
42 import javafx.scene.control.Alert;
43 import javafx.scene.paint.Color;
44 import javafx.scene.shape.Rectangle;
45 import javafx.util.Duration;
46 import junit.framework.AssertionFailedError;
47 import org.junit.After;
48 import org.junit.AfterClass;
49 import org.junit.Before;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.junit.runners.Parameterized;
54 import org.junit.runners.Parameterized.Parameters;
55 import util.Util;
56
57 import static org.junit.Assert.*;
58 import static org.junit.Assume.*;
59 import static util.Util.TIMEOUT;
60
61 /**
62 * Test program for showAndWait functionality.
63 */
64 @RunWith(Parameterized.class)
65 public class ShowAndWaitTest {
66
67 // Maximum number of stages
68 private static final int MAX_STAGES = 10;
69
70 // Used to launch the application before running any test
71 private static final CountDownLatch launchLatch = new CountDownLatch(1);
72
73 // Singleton Application instance
74 private static MyApp myApp;
75
76 // Application class. An instance is created and initialized before running
77 // the first test, and it lives through the execution of all tests.
78 public static class MyApp extends Application {
79 private Stage primaryStage;
194 // test parameters and only runs one in total.
195 //
196 // Consider moving to the setupOnce method.
197 private static boolean test1Run = false;
198 public void ensureTest1() {
199 if (!test1Run) {
200 test1();
201 }
202 }
203
204 @Test
205 public void test1() {
206 if (test1Run) {
207 return;
208 }
209 test1Run = true;
210
211 assertEquals(0, launchLatch.getCount());
212 Util.runAndWait(() -> {
213 assertTrue(Platform.isFxApplicationThread());
214 assertTrue(myApp.primaryStage.isPrimary());
215 assertFalse(myApp.primaryStage.isShowing());
216
217 // Verify that we cannot call showAndWait on the primaryStage
218 try {
219 myApp.primaryStage.showAndWait();
220 throw new AssertionFailedError("Expected IllegalStateException was not thrown");
221 } catch (IllegalStateException ex) {
222 }
223
224 myApp.primaryStage.show();
225 });
226 }
227
228 // Verify that we cannot construct a stage on a thread other than
229 // the FX Application thread
230 @Test (expected=IllegalStateException.class)
231 public void testConstructWrongThread() {
232 ensureTest1();
233 assertFalse(Platform.isFxApplicationThread());
234
235 // The following should throw IllegalStateException
236 tmpStage1 = new TestStage(modality);
237 stages.add(tmpStage1);
238 }
239
240
241 // Verify that we cannot call showAndWait on a thread other than
242 // the FX Application thread
243 @Test (expected=IllegalStateException.class)
244 public void testShowWaitWrongThread() {
245 ensureTest1();
246 assertFalse(Platform.isFxApplicationThread());
247 Util.runAndWait(() -> {
248 tmpStage1 = new TestStage(modality);
249 stages.add(tmpStage1);
250 assertFalse(tmpStage1.isPrimary());
251 assertFalse(tmpStage1.isShowing());
252 });
253 assertNotNull(tmpStage1);
254
255 // The following should throw IllegalStateException
256 tmpStage1.showAndWait();
257 }
258
259 // Verify that we cannot call showAndWait on a visible stage
260 @Test (expected=IllegalStateException.class)
261 public void testVisibleThrow() {
262 ensureTest1();
263 Util.runAndWait(() -> {
264 tmpStage1 = new TestStage(modality);
265 stages.add(tmpStage1);
266 assertFalse(tmpStage1.isPrimary());
267 assertFalse(tmpStage1.isShowing());
268 tmpStage1.show();
269 assertTrue(tmpStage1.isShowing());
270
271 try {
272 // The following should throw IllegalStateException
273 tmpStage1.showAndWait();
274 } finally {
275 tmpStage1.hide();
276 }
277 });
278 }
279
280 // Verify that show returns right away; hide the stage after 500 msec
281 @Test
282 public void testNotBlocking() {
283 ensureTest1();
284
285 final AtomicBoolean stageShowReturned = new AtomicBoolean(false);
286 final AtomicBoolean hideActionReached = new AtomicBoolean(false);
287
288 Runnable rShow = () -> {
289 tmpStage1 = new TestStage(modality);
290 stages.add(tmpStage1);
291 assertFalse(tmpStage1.isPrimary());
292 assertFalse(tmpStage1.isShowing());
293 tmpStage1.show();
294 stageShowReturned.set(true);
295 assertTrue(tmpStage1.isShowing());
296 assertFalse(hideActionReached.get());
297 };
298
299 Runnable rHide = () -> {
300 assertNotNull(tmpStage1);
301 assertTrue(tmpStage1.isShowing());
302 assertTrue(stageShowReturned.get());
303 hideActionReached.set(true);
304 tmpStage1.hide();
305 };
306
307 Util.runAndWait(rShow, rHide);
308
309 assertFalse(tmpStage1.isShowing());
310 }
311
312 // Verify that showAndWait blocks until the stage is hidden.
313 // Verify that the nested event loop exits immediately after
314 // the event handler that calls hide returns, before running
315 // the next Runnable.
316 @Test
317 public void testSingle() {
318 ensureTest1();
319
320 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
321 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
322 final AtomicBoolean nextRunnableReached = new AtomicBoolean(false);
323
324 Runnable rShow1 = () -> {
325 tmpStage1 = new TestStage(modality);
326 stages.add(tmpStage1);
327 assertFalse(tmpStage1.isPrimary());
328 assertFalse(tmpStage1.isShowing());
329 tmpStage1.showAndWait();
330 stage1ShowReturned.set(true);
331 assertFalse(tmpStage1.isShowing());
332 assertTrue(hide1EventReached.get());
333 assertFalse(nextRunnableReached.get());
334 };
335
336 Runnable rHide1 = () -> {
337 hide1EventReached.set(true);
338 assertFalse(stage1ShowReturned.get());
339 assertNotNull(tmpStage1);
340 tmpStage1.hide();
341 Util.sleep(1);
342 assertFalse(stage1ShowReturned.get());
343 };
344
345 Runnable rNext = () -> {
346 // This should happen after the nested event loop exits
347 nextRunnableReached.set(true);
351
352 assertFalse(tmpStage1.isShowing());
353 }
354
355 // Verify that showAndWait blocks until the stage is hidden.
356 // Verify that the nested event loop exits immediately after
357 // the event handler that calls hide returns, before running
358 // the next Runnable (called from rShow1 after showAndWait returns).
359
360 @Test
361 public void testSingle_Chained() {
362 ensureTest1();
363
364 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
365 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
366 final AtomicBoolean nextRunnableReached = new AtomicBoolean(false);
367
368 Runnable rShow1 = () -> {
369 tmpStage1 = new TestStage(modality);
370 stages.add(tmpStage1);
371 assertFalse(tmpStage1.isPrimary());
372 assertFalse(tmpStage1.isShowing());
373 tmpStage1.showAndWait();
374 stage1ShowReturned.set(true);
375 assertFalse(tmpStage1.isShowing());
376 assertTrue(hide1EventReached.get());
377 assertFalse(nextRunnableReached.get());
378 };
379
380 Runnable rHide1 = () -> {
381 hide1EventReached.set(true);
382 assertFalse(stage1ShowReturned.get());
383 assertNotNull(tmpStage1);
384 tmpStage1.hide();
385 Util.sleep(1);
386 assertFalse(stage1ShowReturned.get());
387 Platform.runLater(() -> {
388 // This should happen after the nested event loop exits
389 nextRunnableReached.set(true);
390 });
391 };
392
393 Util.runAndWait(rShow1, rHide1);
394
395 assertFalse(tmpStage1.isShowing());
396 }
397
398 // Verify two nested event loops, with the stages being hidden in the
399 // reverse order that they are shown
400 @Test
401 public void testTwoNested() {
402 ensureTest1();
403
404 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
405 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
406 final AtomicBoolean stage2ShowReturned = new AtomicBoolean(false);
407 final AtomicBoolean hide2EventReached = new AtomicBoolean(false);
408
409 Runnable rShow1 = () -> {
410 tmpStage1 = new TestStage(modality);
411 stages.add(tmpStage1);
412 assertFalse(tmpStage1.isPrimary());
413 assertFalse(tmpStage1.isShowing());
414 tmpStage1.showAndWait();
415 stage1ShowReturned.set(true);
416 assertFalse(tmpStage1.isShowing());
417 assertTrue(stage2ShowReturned.get());
418 assertTrue(hide1EventReached.get());
419 assertTrue(hide2EventReached.get());
420 };
421
422 Runnable rShow2 = () -> {
423 tmpStage2 = new TestStage(modality);
424 stages.add(tmpStage2);
425 assertFalse(tmpStage2.isPrimary());
426 assertFalse(tmpStage2.isShowing());
427 tmpStage2.showAndWait();
428 stage2ShowReturned.set(true);
429 assertFalse(stage1ShowReturned.get());
430 assertFalse(tmpStage2.isShowing());
431 assertTrue(hide2EventReached.get());
432 assertFalse(hide1EventReached.get());
433 };
434
435 Runnable rHide1 = () -> {
436 hide1EventReached.set(true);
437 assertFalse(stage1ShowReturned.get());
438 assertTrue(stage2ShowReturned.get());
439 assertTrue(hide2EventReached.get());
440 assertNotNull(tmpStage1);
441 tmpStage1.hide();
442 Util.sleep(1);
443 assertFalse(stage1ShowReturned.get());
444 };
445
457 Util.runAndWait(rShow1, rShow2, rHide2, rHide1);
458
459 assertFalse(tmpStage1.isShowing());
460 assertFalse(tmpStage2.isShowing());
461 }
462
463 // Verify two nested event loops, with the stages being hidden in the
464 // same order that they are shown
465 @Test
466 public void testTwoInterleaved() {
467 ensureTest1();
468
469 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
470 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
471 final AtomicBoolean stage2ShowReturned = new AtomicBoolean(false);
472 final AtomicBoolean hide2EventReached = new AtomicBoolean(false);
473
474 Runnable rShow1 = () -> {
475 tmpStage1 = new TestStage(modality);
476 stages.add(tmpStage1);
477 assertFalse(tmpStage1.isPrimary());
478 assertFalse(tmpStage1.isShowing());
479 tmpStage1.showAndWait();
480 stage1ShowReturned.set(true);
481 assertFalse(tmpStage1.isShowing());
482 assertTrue(stage2ShowReturned.get());
483 assertTrue(hide1EventReached.get());
484 assertTrue(hide2EventReached.get());
485 };
486
487 Runnable rShow2 = () -> {
488 tmpStage2 = new TestStage(modality);
489 stages.add(tmpStage2);
490 assertFalse(tmpStage2.isPrimary());
491 assertFalse(tmpStage2.isShowing());
492 tmpStage2.showAndWait();
493 stage2ShowReturned.set(true);
494 assertFalse(tmpStage2.isShowing());
495 assertFalse(stage1ShowReturned.get());
496 assertTrue(hide2EventReached.get());
497 assertTrue(hide1EventReached.get());
498 };
499
500 Runnable rHide1 = () -> {
501 hide1EventReached.set(true);
502 assertFalse(stage1ShowReturned.get());
503 assertFalse(stage2ShowReturned.get());
504 assertFalse(hide2EventReached.get());
505 assertNotNull(tmpStage1);
506 tmpStage1.hide();
507 Util.sleep(1);
508 assertFalse(stage1ShowReturned.get());
509 };
510
651 Util.runAndWait(runnables);
652
653 for (int i = 0; i < N; i++) {
654 assertFalse(tmpStage[i].isShowing());
655 }
656 }
657
658 // Verify that Stage.showAndWait throws an exception if called from an
659 // animation timeline.
660 @Test
661 public void testTimeline() throws Throwable {
662 ensureTest1();
663
664 final CountDownLatch animationDone = new CountDownLatch(1);
665 final AtomicReference<Throwable> error = new AtomicReference<>(null);
666
667 KeyFrame kf = new KeyFrame(Duration.millis(200), e -> {
668 try {
669 tmpStage1 = new TestStage(modality);
670 stages.add(tmpStage1);
671 assertFalse(tmpStage1.isPrimary());
672 assertFalse(tmpStage1.isShowing());
673 try {
674 tmpStage1.showAndWait();
675 fail("Did not get expected exception from showAndWait");
676 } catch (IllegalStateException ex) {
677 // Good
678 }
679 assertFalse(tmpStage1.isShowing());
680 } catch (Throwable t) {
681 error.set(t);
682 }
683 animationDone.countDown();
684 });
685 Timeline timeline = new Timeline(kf);
686 timeline.play();
687
688 try {
689 if (!animationDone.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
690 fail("Timeout waiting for animation");
691 }
|
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 javafx.stage.StageShim;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashSet;
32 import java.util.concurrent.CountDownLatch;
33 import java.util.concurrent.TimeUnit;
34 import java.util.concurrent.atomic.AtomicBoolean;
35 import java.util.concurrent.atomic.AtomicReference;
36 import javafx.animation.KeyFrame;
37 import javafx.animation.Timeline;
38 import javafx.application.Application;
39 import javafx.application.Platform;
40 import javafx.print.PrinterJob;
41 import javafx.scene.Group;
42 import javafx.scene.Scene;
43 import javafx.scene.control.Alert;
44 import javafx.scene.paint.Color;
45 import javafx.scene.shape.Rectangle;
46 import javafx.stage.Modality;
47 import javafx.stage.Stage;
48 import javafx.stage.StageShim;
49 import javafx.stage.Window;
50 import javafx.util.Duration;
51 import junit.framework.AssertionFailedError;
52 import org.junit.After;
53 import org.junit.AfterClass;
54 import org.junit.Before;
55 import org.junit.BeforeClass;
56 import org.junit.Test;
57 import org.junit.runner.RunWith;
58 import org.junit.runners.Parameterized;
59 import org.junit.runners.Parameterized.Parameters;
60 import test.util.Util;
61
62 import static org.junit.Assert.*;
63 import static org.junit.Assume.*;
64 import static test.util.Util.TIMEOUT;
65
66 /**
67 * Test program for showAndWait functionality.
68 */
69 @RunWith(Parameterized.class)
70 public class ShowAndWaitTest {
71
72 // Maximum number of stages
73 private static final int MAX_STAGES = 10;
74
75 // Used to launch the application before running any test
76 private static final CountDownLatch launchLatch = new CountDownLatch(1);
77
78 // Singleton Application instance
79 private static MyApp myApp;
80
81 // Application class. An instance is created and initialized before running
82 // the first test, and it lives through the execution of all tests.
83 public static class MyApp extends Application {
84 private Stage primaryStage;
199 // test parameters and only runs one in total.
200 //
201 // Consider moving to the setupOnce method.
202 private static boolean test1Run = false;
203 public void ensureTest1() {
204 if (!test1Run) {
205 test1();
206 }
207 }
208
209 @Test
210 public void test1() {
211 if (test1Run) {
212 return;
213 }
214 test1Run = true;
215
216 assertEquals(0, launchLatch.getCount());
217 Util.runAndWait(() -> {
218 assertTrue(Platform.isFxApplicationThread());
219 assertTrue(StageShim.isPrimary(myApp.primaryStage));
220 assertFalse(myApp.primaryStage.isShowing());
221
222 // Verify that we cannot call showAndWait on the primaryStage
223 try {
224 myApp.primaryStage.showAndWait();
225 throw new AssertionFailedError("Expected IllegalStateException was not thrown");
226 } catch (IllegalStateException ex) {
227 }
228
229 myApp.primaryStage.show();
230 });
231 }
232
233 // Verify that we cannot construct a stage on a thread other than
234 // the FX Application thread
235 @Test (expected=IllegalStateException.class)
236 public void testConstructWrongThread() {
237 ensureTest1();
238 assertFalse(Platform.isFxApplicationThread());
239
240 // The following should throw IllegalStateException
241 tmpStage1 = new TestStage(modality);
242 stages.add(tmpStage1);
243 }
244
245
246 // Verify that we cannot call showAndWait on a thread other than
247 // the FX Application thread
248 @Test (expected=IllegalStateException.class)
249 public void testShowWaitWrongThread() {
250 ensureTest1();
251 assertFalse(Platform.isFxApplicationThread());
252 Util.runAndWait(() -> {
253 tmpStage1 = new TestStage(modality);
254 stages.add(tmpStage1);
255 assertFalse(StageShim.isPrimary(tmpStage1));
256 assertFalse(tmpStage1.isShowing());
257 });
258 assertNotNull(tmpStage1);
259
260 // The following should throw IllegalStateException
261 tmpStage1.showAndWait();
262 }
263
264 // Verify that we cannot call showAndWait on a visible stage
265 @Test (expected=IllegalStateException.class)
266 public void testVisibleThrow() {
267 ensureTest1();
268 Util.runAndWait(() -> {
269 tmpStage1 = new TestStage(modality);
270 stages.add(tmpStage1);
271 assertFalse(StageShim.isPrimary(tmpStage1));
272 assertFalse(tmpStage1.isShowing());
273 tmpStage1.show();
274 assertTrue(tmpStage1.isShowing());
275
276 try {
277 // The following should throw IllegalStateException
278 tmpStage1.showAndWait();
279 } finally {
280 tmpStage1.hide();
281 }
282 });
283 }
284
285 // Verify that show returns right away; hide the stage after 500 msec
286 @Test
287 public void testNotBlocking() {
288 ensureTest1();
289
290 final AtomicBoolean stageShowReturned = new AtomicBoolean(false);
291 final AtomicBoolean hideActionReached = new AtomicBoolean(false);
292
293 Runnable rShow = () -> {
294 tmpStage1 = new TestStage(modality);
295 stages.add(tmpStage1);
296 assertFalse(StageShim.isPrimary(tmpStage1));
297 assertFalse(tmpStage1.isShowing());
298 tmpStage1.show();
299 stageShowReturned.set(true);
300 assertTrue(tmpStage1.isShowing());
301 assertFalse(hideActionReached.get());
302 };
303
304 Runnable rHide = () -> {
305 assertNotNull(tmpStage1);
306 assertTrue(tmpStage1.isShowing());
307 assertTrue(stageShowReturned.get());
308 hideActionReached.set(true);
309 tmpStage1.hide();
310 };
311
312 Util.runAndWait(rShow, rHide);
313
314 assertFalse(tmpStage1.isShowing());
315 }
316
317 // Verify that showAndWait blocks until the stage is hidden.
318 // Verify that the nested event loop exits immediately after
319 // the event handler that calls hide returns, before running
320 // the next Runnable.
321 @Test
322 public void testSingle() {
323 ensureTest1();
324
325 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
326 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
327 final AtomicBoolean nextRunnableReached = new AtomicBoolean(false);
328
329 Runnable rShow1 = () -> {
330 tmpStage1 = new TestStage(modality);
331 stages.add(tmpStage1);
332 assertFalse(StageShim.isPrimary(tmpStage1));
333 assertFalse(tmpStage1.isShowing());
334 tmpStage1.showAndWait();
335 stage1ShowReturned.set(true);
336 assertFalse(tmpStage1.isShowing());
337 assertTrue(hide1EventReached.get());
338 assertFalse(nextRunnableReached.get());
339 };
340
341 Runnable rHide1 = () -> {
342 hide1EventReached.set(true);
343 assertFalse(stage1ShowReturned.get());
344 assertNotNull(tmpStage1);
345 tmpStage1.hide();
346 Util.sleep(1);
347 assertFalse(stage1ShowReturned.get());
348 };
349
350 Runnable rNext = () -> {
351 // This should happen after the nested event loop exits
352 nextRunnableReached.set(true);
356
357 assertFalse(tmpStage1.isShowing());
358 }
359
360 // Verify that showAndWait blocks until the stage is hidden.
361 // Verify that the nested event loop exits immediately after
362 // the event handler that calls hide returns, before running
363 // the next Runnable (called from rShow1 after showAndWait returns).
364
365 @Test
366 public void testSingle_Chained() {
367 ensureTest1();
368
369 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
370 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
371 final AtomicBoolean nextRunnableReached = new AtomicBoolean(false);
372
373 Runnable rShow1 = () -> {
374 tmpStage1 = new TestStage(modality);
375 stages.add(tmpStage1);
376 assertFalse(StageShim.isPrimary(tmpStage1));
377 assertFalse(tmpStage1.isShowing());
378 tmpStage1.showAndWait();
379 stage1ShowReturned.set(true);
380 assertFalse(tmpStage1.isShowing());
381 assertTrue(hide1EventReached.get());
382 assertFalse(nextRunnableReached.get());
383 };
384
385 Runnable rHide1 = () -> {
386 hide1EventReached.set(true);
387 assertFalse(stage1ShowReturned.get());
388 assertNotNull(tmpStage1);
389 tmpStage1.hide();
390 Util.sleep(1);
391 assertFalse(stage1ShowReturned.get());
392 Platform.runLater(() -> {
393 // This should happen after the nested event loop exits
394 nextRunnableReached.set(true);
395 });
396 };
397
398 Util.runAndWait(rShow1, rHide1);
399
400 assertFalse(tmpStage1.isShowing());
401 }
402
403 // Verify two nested event loops, with the stages being hidden in the
404 // reverse order that they are shown
405 @Test
406 public void testTwoNested() {
407 ensureTest1();
408
409 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
410 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
411 final AtomicBoolean stage2ShowReturned = new AtomicBoolean(false);
412 final AtomicBoolean hide2EventReached = new AtomicBoolean(false);
413
414 Runnable rShow1 = () -> {
415 tmpStage1 = new TestStage(modality);
416 stages.add(tmpStage1);
417 assertFalse(StageShim.isPrimary(tmpStage1));
418 assertFalse(tmpStage1.isShowing());
419 tmpStage1.showAndWait();
420 stage1ShowReturned.set(true);
421 assertFalse(tmpStage1.isShowing());
422 assertTrue(stage2ShowReturned.get());
423 assertTrue(hide1EventReached.get());
424 assertTrue(hide2EventReached.get());
425 };
426
427 Runnable rShow2 = () -> {
428 tmpStage2 = new TestStage(modality);
429 stages.add(tmpStage2);
430 assertFalse(StageShim.isPrimary(tmpStage2));
431 assertFalse(tmpStage2.isShowing());
432 tmpStage2.showAndWait();
433 stage2ShowReturned.set(true);
434 assertFalse(stage1ShowReturned.get());
435 assertFalse(tmpStage2.isShowing());
436 assertTrue(hide2EventReached.get());
437 assertFalse(hide1EventReached.get());
438 };
439
440 Runnable rHide1 = () -> {
441 hide1EventReached.set(true);
442 assertFalse(stage1ShowReturned.get());
443 assertTrue(stage2ShowReturned.get());
444 assertTrue(hide2EventReached.get());
445 assertNotNull(tmpStage1);
446 tmpStage1.hide();
447 Util.sleep(1);
448 assertFalse(stage1ShowReturned.get());
449 };
450
462 Util.runAndWait(rShow1, rShow2, rHide2, rHide1);
463
464 assertFalse(tmpStage1.isShowing());
465 assertFalse(tmpStage2.isShowing());
466 }
467
468 // Verify two nested event loops, with the stages being hidden in the
469 // same order that they are shown
470 @Test
471 public void testTwoInterleaved() {
472 ensureTest1();
473
474 final AtomicBoolean stage1ShowReturned = new AtomicBoolean(false);
475 final AtomicBoolean hide1EventReached = new AtomicBoolean(false);
476 final AtomicBoolean stage2ShowReturned = new AtomicBoolean(false);
477 final AtomicBoolean hide2EventReached = new AtomicBoolean(false);
478
479 Runnable rShow1 = () -> {
480 tmpStage1 = new TestStage(modality);
481 stages.add(tmpStage1);
482 assertFalse(StageShim.isPrimary(tmpStage1));
483 assertFalse(tmpStage1.isShowing());
484 tmpStage1.showAndWait();
485 stage1ShowReturned.set(true);
486 assertFalse(tmpStage1.isShowing());
487 assertTrue(stage2ShowReturned.get());
488 assertTrue(hide1EventReached.get());
489 assertTrue(hide2EventReached.get());
490 };
491
492 Runnable rShow2 = () -> {
493 tmpStage2 = new TestStage(modality);
494 stages.add(tmpStage2);
495 assertFalse(StageShim.isPrimary(tmpStage2));
496 assertFalse(tmpStage2.isShowing());
497 tmpStage2.showAndWait();
498 stage2ShowReturned.set(true);
499 assertFalse(tmpStage2.isShowing());
500 assertFalse(stage1ShowReturned.get());
501 assertTrue(hide2EventReached.get());
502 assertTrue(hide1EventReached.get());
503 };
504
505 Runnable rHide1 = () -> {
506 hide1EventReached.set(true);
507 assertFalse(stage1ShowReturned.get());
508 assertFalse(stage2ShowReturned.get());
509 assertFalse(hide2EventReached.get());
510 assertNotNull(tmpStage1);
511 tmpStage1.hide();
512 Util.sleep(1);
513 assertFalse(stage1ShowReturned.get());
514 };
515
656 Util.runAndWait(runnables);
657
658 for (int i = 0; i < N; i++) {
659 assertFalse(tmpStage[i].isShowing());
660 }
661 }
662
663 // Verify that Stage.showAndWait throws an exception if called from an
664 // animation timeline.
665 @Test
666 public void testTimeline() throws Throwable {
667 ensureTest1();
668
669 final CountDownLatch animationDone = new CountDownLatch(1);
670 final AtomicReference<Throwable> error = new AtomicReference<>(null);
671
672 KeyFrame kf = new KeyFrame(Duration.millis(200), e -> {
673 try {
674 tmpStage1 = new TestStage(modality);
675 stages.add(tmpStage1);
676 assertFalse(StageShim.isPrimary(tmpStage1));
677 assertFalse(tmpStage1.isShowing());
678 try {
679 tmpStage1.showAndWait();
680 fail("Did not get expected exception from showAndWait");
681 } catch (IllegalStateException ex) {
682 // Good
683 }
684 assertFalse(tmpStage1.isShowing());
685 } catch (Throwable t) {
686 error.set(t);
687 }
688 animationDone.countDown();
689 });
690 Timeline timeline = new Timeline(kf);
691 timeline.play();
692
693 try {
694 if (!animationDone.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
695 fail("Timeout waiting for animation");
696 }
|