Javax:ListView:通过选择ListView中的项来加载控制器

时间:2017-07-19 11:00:13

标签: java listview javafx javafx-8

我有视图,有ListViewPane。我想将控制器添加为ListView的项目,当我单击其中一个listView的元素时,将Pane的内容设置为其控制器内容,

例如,我有FruitsControllerVegetablesController,当然还有每个控制器的相应.fxml,当我点击第一个元素时,设置Pane个元素a tableView的水果,否则是蔬菜的tableview。我试过whith <fx:include source=Fruits.fxml>等等但我不知道如何切换内容,以及如何在ListView中显示自定义名称作为元素名称。所以你有什么想法吗?

编辑:

我在How can I Populate a ListView in JavaFX using Custom Objects?JavaFX - ListView Item with an Image Button找到了部分解决方案 但问题仍然存在,我不知道如何以及在何处放置<fx:include>标签,以便在我点击某个项目时加载它。

1 个答案:

答案 0 :(得分:1)

您可以使用列表视图的选择模型注册侦听器,并在选择更改时加载相应的视图。

,例如,假设你有

public class View {

    private final String name ;
    private final Class<?> controllerType ;

    // You could assume that the resource is name+".fxml" if you want to rely on conventions like that
    // That would eliminate the need for another field here, but would prevent
    // e.g. names with whitespace etc.
    private final String resource ;

    public View(String name, Class<?> controllerType, String resource) {
        this.name = name ;
        this.controllerType = controllerType ;
        this.resource = resource ;
    }

    public String getName() {
        return name ;
    }

    public Class<?> getControllerType() {
        return controllerType ;
    }

    public String getResource() {
        return resource ;
    }

    @Override
    public String toString() {
        return name ;
    }
}

然后在FXML中:

<!-- imports, namespaces omitted -->

<BorderPane fx:id="root" fx:controller="app.MainController" ... >
    <left>
        <ListView fx:id="selector"/>
    </left>
</BorderPane>

并在控制器中:

package app ;

public class MainController {

    @FXML
    private BorderPane root ;

    @FXML
    private ListView<View> selector ;

    public void initialize() {
        selector.getSelectionModel().selectedItemProperty().addListener((obs, oldView, newView) -> {
            if (newView == null) {
                root.setCenter(null);
            } else {
                // assumes each FXML is in the same package as its controller
                // (which I think is a nice way to organize things)
                FXMLLoader loader = new FXMLLoader(newView.getControllerType().getResource(newView.getResource()));
                try {
                    root.setCenter(loader.load());
                } catch (IOException exc) {
                    // unrecoverable...
                    throw new UncheckedIOException(exc);
                }
            }
        });

        selector.getItems().addAll(
            new View("Fruits", FruitsController.class, "Fruits.fxml"),
            new View("Vegetables", VegetablesController.class, "Vegetables.fxml")
        );
    }
}

如果所有控制器都具有通用功能,则可以使它们实现公共接口(例如ProductsController),并在加载新FXML后使用ProductsController currentController = loader.getController();从加载器中检索当前控制器。 (在这种情况下,您还可以将controllerTypeView的类型更改为Class<? extends ProductsController>。)