简体   繁体   中英

Populate items in tableView using data-binding expression in FXML?

How can I populate items in a tableview using expression referencing model data from controller ? I want to do it within FXML file.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM