Javafx从另一个FXML更新表视图 [英] Javafx Update a tableview from another FXML

查看:86
本文介绍了Javafx从另一个FXML更新表视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参考文章通过JavaFx应用MVC

我具有以下接口1 FXML

I have interface 1 FXML the following

<SplitPane>
    <items>
        <TableView prefHeight="200.0" prefWidth="200.0">
            <columns>
                <TableColumn prefWidth="75.0" text="User" />
                <TableColumn prefWidth="75.0" text="Pass" />
            </columns>
        </TableView>
        <fx:include source="Container.fxml"/>
    </items>
</SplitPane>

Container.fxml仅用于存储xml接口示例,我曾将InputData.fxml,Test.fxml嵌入到TabPanel上

Container.fxml it is only used to store xml interface example I used to embed InputData.fxml,Test.fxml on TabPanel

接口3 InputData.xml我包含textField用户名和密码以及一个保存按钮.

And interface 3 InputData.xml I contains textField the username and password and a save button.

我想问一下,每按一次按钮保存一次,接口1表可以获取值并从接口3的值进行更新

I would like to ask every time I press the button save the,interface 1 table can get value and update from the value of the interface 3

由于接口3输入的data.xml没有直接嵌入接口1中,因此只有在符合条件的情况下才会显示.因此,我无法将数据fxml直接传输到以下内容

Because the interface 3 Input data.xml not embedded directly into the interface 1 it only appears when eligible.So I can not transfer data fxml directly to the following

        DataModel model = new DataModel();
        listController.initModel(model);
        editorController.initModel(model);
        menuController.initModel(model);

如果可以的话请在界面上帮助我

It on the interface if can do please help me

推荐答案

此处有两种方法.

您可以使用

You can inject the controller from the included FXML into the controller for the including FXML using the nested controllers technique. Then the "outer controller" can propagate the model to the "nested controller".

例如如果有

<SplitPane xmlns="..." fx:controller="com.mycompany.MainController">
    <items>
        <TableView prefHeight="200.0" prefWidth="200.0">
            <columns>
                <TableColumn prefWidth="75.0" text="User" />
                <TableColumn prefWidth="75.0" text="Pass" />
            </columns>
        </TableView>
        <fx:include fx:id="container" source="Container.fxml"/>
    </items>
</SplitPane>

假定Container.fxml的控制器类为ContainerController.然后您会这样做:

Suppose the controller class for Container.fxml is ContainerController. Then you would do:

public class MainController {

    private Model model ;

    @FXML
    private ContainerController containerController ; // name is fx:id with "Controller" appended

    public void setModel(Model model) {
        this.model = model ;
        containerController.setModel(model);
        // ...
    }

    // ...
}

当然

public class ContainerController {

    private Model model ;

    public void setModel(Model model) {
        this.model = model ;
        // ...
    }

    // ...
}

使用控制器工厂

如果您有很多包含的FXML文件和控制器等,则可能变得难以维护.在这种情况下,更好的方法可能是在控制器的构造函数中初始化模型,并在FXMLLoader上使用controllerFactory来创建将模型传递给构造函数的控制器.所以现在您的控制器看起来像:

Using a controller factory

If you have a lot of included FXML files and controllers, etc, this can start to get unmaintainable. In that case, a better approach might be to initialize the model in the controllers' constructors, and to use a controllerFactory on the FXMLLoader to create controllers with a model passed to the constructor. So now you controllers look like:

public class MainController {

    private final Model model ;

    public MainController(Model model) {
        this.model = model ;
    }

    public void initialize() {
        // bind controls to model here...
    }
}

,对于ContainerController等类似.请注意,这比以前的版本要干净得多,在以前的版本中,您必须担心在任意时间设置模型.在这里,您可以确保在执行控制器中的任何代码时将其设置.

and similarly for ContainerController, etc. Note this is much cleaner than the previous versions, where you had to worry about the model being set at an arbitrary time. Here you're guaranteed it is set when any code in the controller is executed.

现在,在加载FXML时,FMXLLoader需要一些魔术才能正确创建控制器:

Now you need a bit of magic for the FMXLLoader to create the controllers correctly when the FXML is loaded:

Model model = new Model();
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
Callback<Class<?>, Object> controllerFactory = (Class<?> type) -> {
    try {
        for (Constructor<?> c : type.getConstructors()) {
            if (c.getParameterCount() == 1 && c.getParameterTypes()[0].equals(Model.class)) {
                return c.newInstance(model);
            }
        }
        // couldn't find constructor taking a model, just use default:
        return type.newInstance();
    } catch (Exception exc) {
        exc.printStackTrace();
        return null ;
    }
};
loader.setControllerFactory(controllerFactory);

Parent root = loader.load();
// ...

请注意,通过<fx:include>标记加载的FXML文件将使用与"includes" FXML文件相同的控制器工厂.因此,这将自动将相同的模型传递给嵌套控制器.

Note that FXML files loaded via an <fx:include> tag will use the same controller factory as the "including" FXML file. So this will automatically pass the same model to the nested controller.

最后,如果您确实做了很多事情,则可能要考虑使用依赖项注入框架来为您管理模型上的依赖项. Afterburner.fx 是专用的JavaFX DI框架,然后一切都变得简单

Finally, if you really do a lot of this, you might want to consider using a dependency inject framework to manage the dependencies on the model for you. Afterburner.fx is a dedicated JavaFX DI framework, and then everything is as simple as

public class MainController {

    @Inject 
    private Model model ;

    public void initialize() {
        // bind UI elements to model...
    }
}

您还可以使用Spring或Guice.例如.使用Spring,将控制器配置为原型Bean,将模型配置为单例Bean,然后像afterburner.fx一样编写控制器以注入模型.然后,您可以告诉FXMLLoader使用Spring使用

You can also use Spring or Guice. E.g. with Spring, configure the controllers as prototype beans, the model as a singleton bean, and write the controllers to inject the model as with afterburner.fx. Then you can tell an FXMLLoader to use Spring to create the controllers with

// Spring application context:
ApplicationContext appContext =  ... ;
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(appContext::getBean);
Parent root = loader.load();

这篇关于Javafx从另一个FXML更新表视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆