I want to use JavaFx components inside a JFrame
Java Swing. The application is one JFrame
where there is a button that launches another JFrame
, in which you placed a JFXPanel
to show other JavaFX components.
So, I have this class where it is located main()
:
package JavaGUIPackage;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class EjemploJavaGUI extends JFrame {
private final JLabel lblTitle;
private final JButton btnJFX;
private final LanzarVentana lanzarVentana;
public EjemploJavaGUI() {
setTitle("Ejemplos de GUI ");
setSize(400, 190);
setLocationRelativeTo(null);
getContentPane().setLayout(null);
lanzarVentana = new LanzarVentana();
this.lblTitle = new JLabel("Seleccione un Framework");
this.lblTitle.setBounds(20, 20, 300, 20);
getContentPane().add(this.lblTitle);
this.btnJFX = new JButton("JavaFX");
this.btnJFX.setBounds(20 + 100 + 20, 70, 100, 40);
this.btnJFX.addActionListener(lanzarVentana);
getContentPane().add(this.btnJFX);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public class LanzarVentana implements ActionListener {
private String botonPresionado;
@Override
public void actionPerformed(ActionEvent e) {
this.botonPresionado = e.getActionCommand();
switch(this.botonPresionado) {
case "JavaFX" -> JFXFramework.prender();
}
}
}
public static void main(String[] args) {
EjemploJavaGUI ejemplo= new EjemploJavaGUI();
ejemplo.setVisible(true);
}
}
JFXFramework
I took the class from the Java documentation . I just removed the class main()
so I can call it from the main class:
package JavaGUIPackage;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class JFXFramework {
public JFXFramework() {}
private static void initAndShowGUI() {
// This method is invoked on the EDT thread
JFrame frame = new JFrame("Swing and JavaFX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setSize(300, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on the JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
private static Scene createScene() {
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
Text text = new Text();
text.setX(40);
text.setY(100);
text.setFont(new Font(25));
text.setText("Welcome JavaFX!");
root.getChildren().add(text);
return (scene);
}
public static void prender() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initAndShowGUI();
}
});
}
}
The program compiles without errors, but when I press the button, I get this error:
mar. 21, 2021 1:25:22 P. M. com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @5c7ea94e'
Graphics Device initialization failed for : d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:244)
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:261)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:286)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:160)
at javafx.embed.swing.JFXPanel.lambda$initFx$1(JFXPanel.java:224)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
... 1 more
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: No toolkit found
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:273)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:286)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:160)
at javafx.embed.swing.JFXPanel.lambda$initFx$1(JFXPanel.java:224)
at java.base/java.lang.Thread.run(Thread.java:832)
I put the javafx jar files in a folder next to src in the netbeans project, like this:
Then I added them to the project library, being as follows:
What do I need to modify to display my program correctly?
What happens to you is that the native JavaFX libraries corresponding to the execution platform are not being found (eg, for Windows, the dlls).
This happens because the JARs you are using do not include those libraries. I don't know where you downloaded the ones you're using, but the official ones are published in the central Maven repository. This means that the best option is to use Maven in your project, but if you don't you should make sure to download the specific JARs for your platform.
I'll explain a little better.
Each of the JavaFX modules (controls, fxml, graphics, etc.) is made up of 4 JARs, one is the main one (whose name would be something like javafx-controls.jar for
javafx.controls
) and the other 3 are the ones that contain the libraries native for each of the supported platforms (javafx-controls-win.jar, javafx-controls-linux.jar and javafx-controls-mac.jar). If you don't add these specific JARs to your projects you will have the problems you are having. This would not happen if you were using Maven since the POM of each main JAR is configured to download the specific JAR corresponding to the platform where you are developing.In this link ( https://repo1.maven.org/maven2/org/openjfx/javafx-controls/16/ ) you can see what I tell you about the module
javafx.controls
.