1 /* 2 * Copyright (c) 2019, 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 package test.javafx.embed.swing; 26 27 import com.sun.javafx.PlatformUtil; 28 import org.junit.Assume; 29 import org.junit.Assert; 30 import org.junit.BeforeClass; 31 import org.junit.AfterClass; 32 import org.junit.Test; 33 import junit.framework.AssertionFailedError; 34 35 import javax.swing.JFrame; 36 import javax.swing.JMenu; 37 import javax.swing.JMenuItem; 38 import javax.swing.JMenuBar; 39 import javax.swing.JPanel; 40 import javax.swing.SwingUtilities; 41 import javafx.application.Application; 42 import javafx.application.Platform; 43 import javafx.embed.swing.JFXPanel; 44 import javafx.stage.Stage; 45 import javafx.scene.Group; 46 import javafx.scene.Scene; 47 import java.awt.Dimension; 48 import java.awt.event.InputEvent; 49 import java.awt.event.MouseEvent; 50 import java.util.concurrent.CountDownLatch; 51 import java.util.concurrent.TimeUnit; 52 53 public class JFXPanelTest { 54 // Used to launch the application before running any test 55 private static final CountDownLatch launchLatch = new CountDownLatch(1); 56 57 // Application class. An instance is created and initialized before running 58 // the first test, and it lives through the execution of all tests. 59 public static class MyApp extends Application { 60 @Override 61 public void start(Stage primaryStage) throws Exception { 62 Platform.setImplicitExit(false); 63 Assert.assertTrue(Platform.isFxApplicationThread()); 64 Assert.assertNotNull(primaryStage); 65 66 launchLatch.countDown(); 67 } 68 } 69 70 @BeforeClass 71 public static void doSetupOnce() throws Exception { 72 // Start the Application 73 new Thread(() -> Application.launch(MyApp.class, (String[]) null)).start(); 74 75 if (!launchLatch.await(5000, TimeUnit.MILLISECONDS)) { 76 throw new AssertionFailedError("Timeout waiting for Application to launch"); 77 } 78 79 Assert.assertEquals(0, launchLatch.getCount()); 80 } 81 82 @AfterClass 83 public static void doTeardownOnce() { 84 Platform.exit(); 85 } 86 87 static class TestFXPanel extends JFXPanel { 88 protected void processMouseEventPublic(MouseEvent e) { 89 processMouseEvent(e); 90 } 91 }; 92 93 @Test 94 public void testNoDoubleClickOnFirstClick() throws Exception { 95 96 CountDownLatch firstPressedEventLatch = new CountDownLatch(1); 97 98 // It's an array, so we can mutate it inside of lambda statement 99 int[] pressedEventCounter = {0}; 100 101 SwingUtilities.invokeLater(() -> { 102 TestFXPanel dummyFXPanel = new TestFXPanel(); 103 dummyFXPanel.setPreferredSize(new Dimension(100, 100)); 104 TestFXPanel fxPnl = new TestFXPanel(); 105 fxPnl.setPreferredSize(new Dimension(100, 100)); 106 JFrame jframe = new JFrame(); 107 JPanel jpanel = new JPanel(); 108 jpanel.add(dummyFXPanel); 109 jpanel.add(fxPnl); 110 jframe.setContentPane(jpanel); 111 jframe.pack(); 112 jframe.setVisible(true); 113 114 Platform.runLater(() -> { 115 Scene dummyScene = new Scene(new Group()); 116 dummyFXPanel.setScene(dummyScene); 117 Scene scene = new Scene(new Group()); 118 fxPnl.setScene(scene); 119 120 scene.addEventHandler(javafx.scene.input.MouseEvent.MOUSE_PRESSED, (event -> { 121 pressedEventCounter[0] += 1; 122 firstPressedEventLatch.countDown(); 123 })); 124 125 SwingUtilities.invokeLater(() -> { 126 MouseEvent e = new MouseEvent(fxPnl, MouseEvent.MOUSE_PRESSED, 0, MouseEvent.BUTTON1_DOWN_MASK, 127 5, 5, 1, false, MouseEvent.BUTTON1); 128 129 fxPnl.processMouseEventPublic(e); 130 }); 131 }); 132 }); 133 134 Assert.assertTrue(firstPressedEventLatch.await(5000, TimeUnit.MILLISECONDS)); 135 136 Thread.sleep(500); // there should be no pressed event after the initial one. Let's wait for 0.5s and check again. 137 138 Assert.assertEquals(1, pressedEventCounter[0]); 139 } 140 141 @Test 142 public void testClickOnEmptyJFXPanel() throws Exception { 143 CountDownLatch firstPressedEventLatch = new CountDownLatch(1); 144 145 SwingUtilities.invokeLater(() -> { 146 TestFXPanel fxPnl = new TestFXPanel(); 147 148 MouseEvent e = new MouseEvent(fxPnl, MouseEvent.MOUSE_PRESSED, 0, MouseEvent.BUTTON1_DOWN_MASK, 149 5, 5, 1, false, MouseEvent.BUTTON1); 150 151 fxPnl.processMouseEventPublic(e); 152 153 firstPressedEventLatch.countDown(); 154 }); 155 156 Assert.assertTrue(firstPressedEventLatch.await(5000, TimeUnit.MILLISECONDS)); 157 } 158 } 159