A DESCRIPTION OF THE PROBLEM :
The secondary event loop introduced as a means of synchronization with the JavaFX Application thread in [1] never terminates as the SecondaryLoop.exit() call is not reached because the thread is blocked in the SecondaryLoop.enter() call.
[1]
https://github.com/javafxports/openjdk-jfx/commit/b66d0816dbef4e1f55153d268770f3dfff3d910f
https://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/bbbc628eda2d
REGRESSION : Last worked in version 8u221
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Have a JFXPanel instance, call its setScene() method on any other thread than the JavaFX Application thread.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The method call returns.
ACTUAL -
The method call never returns.
CUSTOMER SUBMITTED WORKAROUND :
Subclass JFXPanel as below and use that subclass instead.
import java.awt.EventQueue;
import java.awt.SecondaryLoop;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
public class MyJFXPanel extends JFXPanel {
@Override
public void setScene(Scene newScene) {
if (Platform.isFxApplicationThread()) {
super.setScene(newScene);
} else {
EventQueue eventQueue = AccessController.doPrivileged(
(PrivilegedAction<EventQueue>) java.awt.Toolkit
.getDefaultToolkit()::getSystemEventQueue);
SecondaryLoop secondaryLoop = eventQueue.createSecondaryLoop();
Platform.runLater(() -> {
super.setScene(newScene);
secondaryLoop.exit();
});
secondaryLoop.enter();
}
}
}
FREQUENCY : always
The secondary event loop introduced as a means of synchronization with the JavaFX Application thread in [1] never terminates as the SecondaryLoop.exit() call is not reached because the thread is blocked in the SecondaryLoop.enter() call.
[1]
https://github.com/javafxports/openjdk-jfx/commit/b66d0816dbef4e1f55153d268770f3dfff3d910f
https://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/bbbc628eda2d
REGRESSION : Last worked in version 8u221
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Have a JFXPanel instance, call its setScene() method on any other thread than the JavaFX Application thread.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The method call returns.
ACTUAL -
The method call never returns.
CUSTOMER SUBMITTED WORKAROUND :
Subclass JFXPanel as below and use that subclass instead.
import java.awt.EventQueue;
import java.awt.SecondaryLoop;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
public class MyJFXPanel extends JFXPanel {
@Override
public void setScene(Scene newScene) {
if (Platform.isFxApplicationThread()) {
super.setScene(newScene);
} else {
EventQueue eventQueue = AccessController.doPrivileged(
(PrivilegedAction<EventQueue>) java.awt.Toolkit
.getDefaultToolkit()::getSystemEventQueue);
SecondaryLoop secondaryLoop = eventQueue.createSecondaryLoop();
Platform.runLater(() -> {
super.setScene(newScene);
secondaryLoop.exit();
});
secondaryLoop.enter();
}
}
}
FREQUENCY : always
- duplicates
-
JDK-8235843 JFXPanel fails to render if setScene called on Swing thread
- Closed
- relates to
-
JDK-8089005 JFXPanel.setScene(Scene) uses bad synchronization pattern
- Resolved