Issue
A simple question but I cannot find an answer. I have one FXML file that I would like to instantiate multiple times. Each copy would need it's own handle so I could change data therein. Hypothetically, this is exactly like using the "new" keyword on a class you just created.
In my attempts so far, I have been able to create multiple copies of the fxml file, but there is only one controller, so calling methods means the changes happen to all the copies.
Do I have to create a new controller for every copy of the same fxml file?
Thanks In advance
EDIT
The code I am working this idea out on is here:
JavaFX : Pass parameters while instantiating controller class
Just in case some background may help:
I have a scene that I want to hold multiple instances of a FXML file I made. Setting one FXML file in the scene is easy, but creating multiple (10-20) means I would have 10 to 20 controllers and 10 to 20 instances of the FXML file. Is there a cleaner way to do this?
My hope was to do something like this:
public class SampleController implements Initializable {
@FXML
Label firstName;
@FXML
Label lastName;
public SampleController(Label firstname, Label lastname) {
this.firstName = firstname;
this.lastName = lastname;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
Then call something like:
SampleController Row1 = new SampleController("my", "name");
and have this command load the attached FXML file to the scene along with the data I passed it. But this does not work, it crashes with an exception.
Solution
The following demonstrates constructing two instances of an fxml
file, and obtaining a reference to their controllers:
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<children>
<Label fx:id="label" />
</children>
<opaqueInsets>
<Insets top="10.0" />
</opaqueInsets>
</Pane>
Controller.java its controller
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class Controller{
@FXML
public Label label;
public void setText(String text) {
label.setText(text);
}
}
Use two instances of Main.fxml
:
@Override
public void start(final Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader();
Pane topPane = loader.load(getClass().getResource("xml/Main.fxml").openStream());
Controller controllerOfTop = loader.getController();
controllerOfTop.setText("Top");
loader = new FXMLLoader();
Pane bottomPane = loader.load(getClass().getResource("xml/Main.fxml").openStream());
Controller controllerOfBottom = loader.getController();
controllerOfBottom.setText("Bottom");
Scene scene = new Scene(new VBox(topPane, bottomPane));
primaryStage.setScene(scene);
primaryStage.show();
}
Answered By - c0der
Answer Checked By - Marie Seifert (JavaFixing Admin)