3

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.

comfychair
  • 43
  • 6
  • 3
    "In my attempts so far, I have been able to create multiple copies of the fxml file" please post [mcve] of your code. " but there is only one controller" there is one controller class, but each `fxml` should have its own instance of it. – c0der Feb 08 '19 at 06:56

1 Answers1

6

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();
}
c0der
  • 18,467
  • 6
  • 33
  • 65
  • 1
    I see, so it's a new fxml loader every time, that is what I was missing. What if there were 10+ instances or maybe more? From a design or efficiency perspective, is there anything you would do differently? – comfychair Feb 08 '19 at 13:48
  • 1
    If there are lots of instances, you will probably be encroaching on UI Virtualization. Here is a `ListView` [example](https://stackoverflow.com/questions/19588029/customize-listview-in-javafx-with-fxml). The same can be done with `TableView` and other nodes that use virtualization. – SedJ601 Feb 08 '19 at 14:28
  • 1
    Thanks @Sedrick, you taught me something new. This project wont have that many entries, maybe 20 max. My above comment was asking if I did have 20 instances, I would have 20 controllers to keep up with in order to make changes to the Labels. Is this good design? – comfychair Feb 08 '19 at 22:26