Skip to content

Commit 794ffc0

Browse files
8231372: JFXPanel fails to render if setScene called on Swing thread
Correctly terminate secondary event loop in JFXPanel::setScene Co-authored-by: Michal Růžička <michal.ruza@gmail.com> Reviewed-by: psadhukhan, arapte
1 parent e7dbdfc commit 794ffc0

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

modules/javafx.swing/src/main/java/javafx/embed/swing/JFXPanel.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,14 @@ public void setScene(final Scene newScene) {
299299
(PrivilegedAction<EventQueue>) java.awt.Toolkit
300300
.getDefaultToolkit()::getSystemEventQueue);
301301
SecondaryLoop secondaryLoop = eventQueue.createSecondaryLoop();
302-
if (secondaryLoop.enter()) {
303-
Platform.runLater(() -> {
302+
Platform.runLater(() -> {
303+
try {
304304
setSceneImpl(newScene);
305-
});
306-
secondaryLoop.exit();
307-
}
305+
} finally {
306+
secondaryLoop.exit();
307+
}
308+
});
309+
secondaryLoop.enter();
308310
}
309311
}
310312

tests/system/src/test/java/test/javafx/embed/swing/JFXPanelTest.java

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.junit.Assume;
2929
import org.junit.Assert;
3030
import org.junit.BeforeClass;
31+
import org.junit.After;
3132
import org.junit.AfterClass;
3233
import org.junit.Test;
3334
import junit.framework.AssertionFailedError;
@@ -54,6 +55,8 @@ public class JFXPanelTest {
5455
// Used to launch the application before running any test
5556
private static final CountDownLatch launchLatch = new CountDownLatch(1);
5657

58+
JFrame jframe;
59+
5760
// Application class. An instance is created and initialized before running
5861
// the first test, and it lives through the execution of all tests.
5962
public static class MyApp extends Application {
@@ -84,6 +87,13 @@ public static void doTeardownOnce() {
8487
Platform.exit();
8588
}
8689

90+
@After
91+
public void doCleanup() {
92+
if (jframe != null) {
93+
SwingUtilities.invokeLater(() -> jframe.dispose());
94+
}
95+
}
96+
8797
static class TestFXPanel extends JFXPanel {
8898
protected void processMouseEventPublic(MouseEvent e) {
8999
processMouseEvent(e);
@@ -103,7 +113,7 @@ public void testNoDoubleClickOnFirstClick() throws Exception {
103113
dummyFXPanel.setPreferredSize(new Dimension(100, 100));
104114
TestFXPanel fxPnl = new TestFXPanel();
105115
fxPnl.setPreferredSize(new Dimension(100, 100));
106-
JFrame jframe = new JFrame();
116+
jframe = new JFrame();
107117
JPanel jpanel = new JPanel();
108118
jpanel.add(dummyFXPanel);
109119
jpanel.add(fxPnl);
@@ -155,5 +165,58 @@ public void testClickOnEmptyJFXPanel() throws Exception {
155165

156166
Assert.assertTrue(firstPressedEventLatch.await(5000, TimeUnit.MILLISECONDS));
157167
}
158-
}
159168

169+
@Test
170+
public void setSceneOnFXThread() throws Exception {
171+
172+
CountDownLatch completionLatch = new CountDownLatch(1);
173+
174+
SwingUtilities.invokeLater(() -> {
175+
JFXPanel fxPanel = new JFXPanel();
176+
fxPanel.setPreferredSize(new Dimension(100, 100));
177+
jframe = new JFrame();
178+
JPanel jpanel = new JPanel();
179+
jpanel.add(fxPanel);
180+
jframe.add(jpanel);
181+
jframe.pack();
182+
jframe.setVisible(true);
183+
184+
Platform.runLater(() -> {
185+
Scene scene = new Scene(new Group());
186+
fxPanel.setScene(scene);
187+
completionLatch.countDown();
188+
});
189+
});
190+
191+
Assert.assertTrue("Timeout waiting for setScene to complete",
192+
completionLatch.await(5000, TimeUnit.MILLISECONDS));
193+
}
194+
195+
@Test
196+
public void setSceneOnSwingThread() throws Exception {
197+
198+
CountDownLatch completionLatch = new CountDownLatch(1);
199+
200+
SwingUtilities.invokeLater(() -> {
201+
JFXPanel fxPanel = new JFXPanel();
202+
fxPanel.setPreferredSize(new Dimension(100, 100));
203+
jframe = new JFrame();
204+
JPanel jpanel = new JPanel();
205+
jpanel.add(fxPanel);
206+
jframe.add(jpanel);
207+
jframe.pack();
208+
jframe.setVisible(true);
209+
210+
Platform.runLater(() -> {
211+
Scene scene = new Scene(new Group());
212+
SwingUtilities.invokeLater(() -> {
213+
fxPanel.setScene(scene);
214+
completionLatch.countDown();
215+
});
216+
});
217+
});
218+
219+
Assert.assertTrue("Timeout waiting for setScene to complete",
220+
completionLatch.await(5000, TimeUnit.MILLISECONDS));
221+
}
222+
}

0 commit comments

Comments
 (0)