1 /* 2 * Copyright (c) 2012, 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 com.sun.javafx.application; 27 28 import javafx.application.Platform; 29 import javafx.embed.swing.JFXPanel; 30 import javafx.scene.Group; 31 import javafx.scene.Scene; 32 import javafx.scene.paint.Color; 33 import junit.framework.AssertionFailedError; 34 import util.Util; 35 36 import javax.swing.JFrame; 37 import javax.swing.SwingUtilities; 38 import java.awt.BorderLayout; 39 import java.awt.Dimension; 40 import java.lang.reflect.InvocationTargetException; 41 import java.util.concurrent.CountDownLatch; 42 import java.util.concurrent.TimeUnit; 43 import java.util.concurrent.atomic.AtomicReference; 44 45 import org.junit.Test; 46 import org.junit.Assert; 47 48 /** 49 * Test program for Platform.exit() behavior with an embedded JFXPanel. 50 */ 51 public class SwingNoExit { 52 53 // Sleep time showing/hiding window in milliseconds 54 private static final int SLEEP_TIME = 1000; 55 56 private JFrame frame; 57 private JFXPanel fxPanel; 58 59 public void init() { 60 // Create Swing window 61 frame = new JFrame("JFXPanel 1"); 62 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 63 frame.setLayout(new BorderLayout()); 64 65 // Create javafx panel 66 fxPanel = new JFXPanel(); 67 fxPanel.setPreferredSize(new Dimension(210, 180)); 68 frame.getContentPane().add(fxPanel, BorderLayout.CENTER); 69 70 // Create scene and add it to the panel 71 Util.runAndWait(() -> { 72 Group root = new Group(); 73 Scene scene = new Scene(root); 74 scene.setFill(Color.LIGHTYELLOW); 75 fxPanel.setScene(scene); 76 }); 77 78 // show frame 79 frame.setLocationRelativeTo(null); 80 frame.pack(); 81 frame.setVisible(true); 82 } 83 84 @Test 85 public void doTestImplicitExit() throws Throwable { 86 final AtomicReference<Throwable> error = new AtomicReference<>(null); 87 88 final CountDownLatch initLatch = new CountDownLatch(1); 89 SwingUtilities.invokeLater(() -> { 90 try { 91 init(); 92 initLatch.countDown(); 93 } catch (Throwable th) { 94 error.set(th); 95 } 96 }); 97 if (!initLatch.await(Util.TIMEOUT, TimeUnit.MILLISECONDS)) { 98 throw new AssertionFailedError("Timeout waiting for JFXPanel to launch and initialize"); 99 } 100 Throwable t = error.get(); 101 if (t != null) { 102 throw t; 103 } 104 105 final CountDownLatch runAndWait = new CountDownLatch(1); 106 Platform.runLater(() -> { 107 Platform.exit(); 108 runAndWait.countDown(); 109 }); 110 if (!runAndWait.await(Util.TIMEOUT, TimeUnit.MILLISECONDS)) { 111 throw new AssertionFailedError("Timeout waiting for Platform.exit()"); 112 } 113 114 final CountDownLatch exitLatch = PlatformImpl.test_getPlatformExitLatch(); 115 Thread.sleep(SLEEP_TIME); 116 // Platform.exit() should not cause FX to exit, while JFXPanel is alive 117 Assert.assertEquals("Platform.exit() caused FX to exit, while JFXPanel is alive", 118 1, exitLatch.getCount()); 119 120 try { 121 SwingUtilities.invokeAndWait(() -> { 122 frame.setVisible(false); 123 frame.dispose(); 124 }); 125 } 126 catch (InvocationTargetException ex) { 127 throw new AssertionFailedError("Exception while disposing JFrame"); 128 } 129 130 Thread.sleep(SLEEP_TIME); 131 // JFXPanel is gone, implicit exit is false, so FX should have exited now 132 Assert.assertEquals("FX is not exited, when the last JFXPanel is disposed", 133 0, exitLatch.getCount()); 134 } 135 }