Reputation: 26587
How can I populate items in a tableview using expression referencing model data from controller ? I want to do it within FXML file.
Upvotes: 1
Views: 359
Reputation: 209225
You can just about make this work by putting the model into the FXMLLoader
's namespace before you load the FXML. It involves a fair amount of wiring between the controller, model, and FXMLLoader.
Given
public class Model {
public ObservableList<SomeDataType> getTableItems() {
// ...
}
}
and an FXML file View.fxml with
<!-- root element: -->
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.Controller">
<TableView fx:id="table" items="${model.tableItems}">
<!-- ... -->
</TableView>
<!-- ... -->
</BorderPane>
Then you can do the following:
Model model = new Model();
// configure model as needed...
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
loader.getNamespace().put("model", model);
Parent root = loader.load();
// etc
Note that this will not allow the usual FXML-injection of the model into the controller, as you might expect (I think this is an oversight...). So simply doing
public class Controller {
@FXML
private Model model ;
// ...
}
won't give you access to the model in the controller. If you need this, which you likely do, then you need to set it manually:
Model model = new Model();
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
loader.getNamespace().put("model", model);
Parent root = loader.load();
Controller controller = loader.getController();
controller.setModel(model);
with the obvious setModel(...)
method defined in Controller
.
If you need access to the model in the controller's initialize()
method, then you need to go one step further:
Model model = new Model();
Controller controller = new Controller();
controller.setModel(model); // or define a constructor taking the model...
FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
loader.getNamespace().put("model", model);
loader.setController(controller);
Parent root = loader.load();
In this version, you must remove the <fx:controller>
attribute from the FXML file (as the controller has already been set).
Given all the complex wiring needed to get this to work, it's probably better just to set the table's items in the controller's initialize method.
Upvotes: 3