Solution for How do you embed a Swing JPanel into a JavaFX frame?
is Given Below:
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();
}
});
}
}
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:
- Interoperability between Graphics2D and GraphicsContext
Specifically, consider using the FXGraphics2D library:
FXGraphics2D is an implementation of Java2D’s Graphics2D API that targets a JavaFX canvas.