Issue
From Integrating JavaFX 2.0 with Swing and SWT there is a code that allows you to embed a JFXPanel inside a Swing JFrame. I was wondering is there a reverse of that where a JPanel is embedded inside an Application
or Stage
which is the equivalent of JFrame
as noted in Converting from Swing to JavaFX?
/**
* Simple class demonstrating interoperability between Swing and JavaFX. This
* class is adapted from the example provided in the Javadoc documentation for
* {@code javafx.embed.swing.JFXPanel}.
*/
public class SwingJavaFxInteroperabilityDemo
{
private static void initAndShowGUI()
{
// This method is invoked on Swing thread
final JFrame frame = new JFrame("JavaFX / Swing Integrated");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
Platform.runLater(new Runnable()
{
@Override
public void run()
{
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel)
{
// This method is invoked on JavaFX thread
final Scene scene = TextIntegrationSceneCreator.createTextScene();
fxPanel.setScene(scene);
}
public static void main(String[] arguments)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
initAndShowGUI();
}
});
}
}
Solution
You can use a SwingNode
to place swing content into a JavaFX node.
Sample Application
There is an example application in the SwingNode documentation previously linked:
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javax.swing.*;
public class SwingFx extends Application {
@Override
public void start(Stage stage) {
final SwingNode swingNode = new SwingNode();
createAndSetSwingContent(swingNode);
StackPane pane = new StackPane();
pane.getChildren().add(swingNode);
stage.setScene(new Scene(pane, 100, 50));
stage.show();
}
private void createAndSetSwingContent(
final SwingNode swingNode
) {
SwingUtilities.invokeLater(() ->
swingNode.setContent(
new JButton("Click me!")
)
);
}
public static void main(String[] args) {
launch(args);
}
}
Dependency and Module Management
If you are using Maven or Gradle for your JavaFX dependencies, you can import the library for JavaFX/Swing integration using:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>16</version>
</dependency>
If you are writing a modular application using Jigsaw capabilities, placing the following in your module-info.java
file will make the JavaFX swing integration module visible to your application:
requires javafx.swing;
Embedding Swing in JavaFX Tutorial
Oracle provides a good tutorial for embedding Swing content in JavaFX:
The tutorial is written for Java 8 but is still relevant. The tutorial covers topics such as thread management and event handling, and I advise anybody attempting the integration of JavaFX and Swing to understand those topics very well before attempting integration, otherwise bad and unpredictable things may occur.
In general, I advise not mixing JavaFX and Swing code unless that is absolutely necessary for your application.
Canvas Integration and Heavyweight Swing Components
Note, from the SwingNode documentation:
The hierarchy of components contained in the
JComponent
instance should not contain any heavyweight components, otherwise,SwingNode
may fail to paint it.
An example of a heavyweight component is a Canvas
. If you wish to use an awt canvas in JavaFX, see:
Specifically, consider using the FXGraphics2D library:
FXGraphics2D is an implementation of Java2D's Graphics2D API that targets a JavaFX canvas.
Maven doesn't know a javafx.embed.swing. Any idea where to find it?
This should not be the case for a properly configured Maven setup.
All of the JavaFX framework modules are in the central maven repository.
The central maven repository is enabled by default in a standard Maven installation.
The maven coordinates for javafx-swing are already in this answer (under the section titled "Dependency and Module Management").
Update the dependency version to match the JavaFX version you are using.
The recent stable version of the dependency is 18.0.1 today, so to use that, ensure that all javafx components that you rely on use that version for their JavaFX dependencies.
Alternately, you can
However, I recommend using dependencies on your Maven or Gradle build tools rather than relying on manually downloaded modules or the JavaFX SDK.
Answered By - jewelsea
Answer Checked By - Mildred Charles (JavaFixing Admin)