I'm new to using JavaFX and I'm having some issues figuring out how to integrate an fxml file, in my swing application. Reading online I've found a way to load the fxml file,and displaying it on screen following this guide: Integrating JavaFX into Swing Applications
what my code is supposed to do is to load the fxml file, that I've started to design with JavaFX Scene Builder, add the JFXPanel to a JPanel, and return it through a method call. this then gets added to a tabbedPanel in the main application (so there might be multiple distinct JFXPanel open at the same time).
I've kind of figured out some of the problems, but I'm not sure if how to continue. I was able to run one panel, but as in the tutorial I posted, static methods are used, and so I was unable to have multiple distinct panels. I made some changes, but now I'm completely stuck.
This is my current FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="GUI.fcmModeler.fcmPanel">
<children>
<AnchorPane prefHeight="25.0" prefWidth="1000.0">
<children>
<Button fx:id="addComponent" layoutX="161.0" mnemonicParsing="false" onMouseClicked="#addComponent" prefHeight="25.0" prefWidth="600.0" text="+ Add Component" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<SplitPane dividerPositions="0.1713426853707415" layoutY="25.0" prefHeight="577.0" prefWidth="1000.0">
<items>
<AnchorPane fx:id="leftPane" maxWidth="160.0" minHeight="0.0" minWidth="160.0" prefHeight="575.0" prefWidth="160.0" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="546.0" prefWidth="683.0" />
</items>
</SplitPane>
</children>
</Pane>
And this is my controller class:
package GUI.fcmModeler;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javax.swing.*;
import java.io.IOException;
import java.util.Random;
public class fcmPanel extends JPanel {
private JPanel frame;
private static Group root=new Group();
private boolean firstRun=true;
Scene scene=null;
private void initAndShowGUI() {
// This method is invoked on the EDT thread
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setSize(1200, 1200);
frame.setVisible(true);
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(fxPanel);
}
});
frame.add(fxPanel);
frame.setVisible(true);
}
private void initFX(JFXPanel fxPanel) {
// This method is invoked on the JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
private Scene createScene() {
//if(firstRun){
//root = new Group();
if(scene==null) {
scene = new Scene(root, Color.ALICEBLUE);
}
try {
Node newLoadedPane = FXMLLoader.load(fcmPanel.class.getResource("/fxml/fcmPanel.fxml"));
root.getChildren().add(newLoadedPane);
} catch (IOException e) {
System.out.print("the file doesn'e exist.\n");
e.printStackTrace();
}
//}
return (scene);
}
public JPanel returnPanel() {
System.out.println("returnpanel");
// if(frame==null){
// frame = new JPanel();
// }
//initFcmPanel();
return frame;
}
public fcmPanel(){
frame = new JPanel();
//root=g;
initFcmPanel();
}
public void initFcmPanel() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initAndShowGUI();
}
});
}
public void addComponent(){
Platform.runLater(new Runnable() {
@Override
public void run() {
System.out.println("added component2");
Circle circle = new Circle(new Random().nextInt(50),Color.BLUE);
root.getChildren().add(circle);
circle.relocate(new Random().nextInt(600),new Random().nextInt(600));
}
});
}
}
The JFXPanel get added to the tabbed panel through this call:
tabbedPanel.addTab(newTabName , null,new fcmPanel().returnPanel(), filePath );
As it is right now, I'm facing the following problem
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Group@3e0f3500[styleClass=root]is already set as root of another scene
I understand the error message,but I don't know how to solve it.
Thank you in advance.