Uitableview Javafx从另一个FXML更新tableview

Uitableview Javafx从另一个FXML更新tableview,uitableview,javafx,fxml,Uitableview,Javafx,Fxml,参考文章 我有接口1 FXML,如下所示 <SplitPane> <items> <TableView prefHeight="200.0" prefWidth="200.0"> <columns> <TableColumn prefWidth="75.0" text="User" /> <TableColumn pre

参考文章

我有接口1 FXML,如下所示

<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>
它在界面上如果可以做的话,请帮我这里的两种方法

将模型传递给嵌套控制器 您可以使用以下技术将控制器从包含的FXML注入包含的FXML的控制器。然后“外部控制器”可以将模型传播到“嵌套控制器”

所以,例如,如果你有


假设
Container.fxml
的控制器类是
ContainerController
。然后你会做:

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文件和控制器等,这可能会开始变得无法维护。在这种情况下,更好的方法可能是在控制器的构造函数中初始化模型,并在
fxmloader
上使用
controllerFactory
来创建具有传递给构造函数的模型的控制器。现在您的控制器看起来像:

public class MainController {

    private final Model model ;

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

    public void initialize() {
        // bind controls to model here...
    }
}
同样,对于
ContainerController
等,请注意,这比以前的版本要干净得多,在以前的版本中,您必须担心在任意时间设置模型。在这里,您可以保证它是在控制器中的任何代码执行时设置的

现在,您需要为
FMXLLoader
添加一点魔力,以便在加载FXML时正确创建控制器:

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();
// ...
您还可以使用Spring或Guice。例如,使用Spring,将控制器配置为原型bean,将模型配置为单例bean,并编写控制器以注入模型,就像使用afterburner.fx一样。然后,您可以告诉
fxmloader
使用Spring创建具有

// Spring application context:
ApplicationContext appContext =  ... ;
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(appContext::getBean);
Parent root = loader.load();
这里有两种方法

将模型传递给嵌套控制器 您可以使用以下技术将控制器从包含的FXML注入包含的FXML的控制器。然后“外部控制器”可以将模型传播到“嵌套控制器”

所以,例如,如果你有


假设
Container.fxml
的控制器类是
ContainerController
。然后你会做:

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文件和控制器等,这可能会开始变得无法维护。在这种情况下,更好的方法可能是在控制器的构造函数中初始化模型,并在
fxmloader
上使用
controllerFactory
来创建具有传递给构造函数的模型的控制器。现在您的控制器看起来像:

public class MainController {

    private final Model model ;

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

    public void initialize() {
        // bind controls to model here...
    }
}
同样,对于
ContainerController
等,请注意,这比以前的版本要干净得多,在以前的版本中,您必须担心在任意时间设置模型。在这里,您可以保证它是在控制器中的任何代码执行时设置的

现在,您需要为
FMXLLoader
添加一点魔力,以便在加载FXML时正确创建控制器:

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();
// ...
您还可以使用Spring或Guice。例如,使用Spring,将控制器配置为原型bean,将模型配置为单例bean,并编写控制器以注入模型,就像使用afterburner.fx一样。然后,您可以告诉
fxmloader
使用Spring创建具有

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

使用MVC方法:在两个控制器之间共享一个模型,并使数据可以从模型中访问。请参阅感谢您的详细说明和完整源代码James_D有点贪婪,但我还有一个问题要问扩展数据更新从另一个FXML更新tableview。期待您的帮助:使用MVC方法:在两个控制器之间共享模型,并使数据可从模型访问。请参阅感谢您的详细说明和完整源代码James_D有点贪婪,但是我还有一个问题要问扩展数据更新从另一个FXML更新tableview。期待您的帮助:DMethod 1:要在接口1 Main.FXML和接口3 InputData.FXML之间传递值。例如,我需要传输Container.FXML的公共值模型,如果我有多个容器xml接口:container.fxml包含container2.fxml包含InputData。我需要从Main.fxml=model->container.fxml=model->container2.fxml=model->InputData.fxml传输模型方法2:我不需要understand@MaT–我不确定我是否真的理解您最后一条评论中的问题:您已经准确地描述了它应该如何工作。每个需要模型参考的控制器都有一个
setModel
方法。如果嵌套控制器也需要访问模型,则其
setModel
方法调用嵌套控制器的
setModel
方法。你可以根据需要将其嵌套得很深,但正如我所说的,它可能会变得复杂,在这一点上,控制器工厂可能会更容易。嗨,詹姆斯,谢谢你的详细说明,我理解方法1,如果嵌套接口太多,这将成为一个问题。您的方法2非常方便,但我不知道如何执行。我可以创建有关方法2的主题,敦促您继续帮助方法1:以便在接口1 Main.fxml和接口3 InputData.fxml之间传递值。例如,我需要传输Container.fxml的公共值模型,如果我有多个容器xml接口:container.fxml包含container2.fxml包含InputData。我需要从Main.fxml=model->container.fxml=model->container2.fxml=model->InputData.fxml传输模型方法2:我不需要understand@MaT–我不确定我是否真的理解您最后一条评论中的问题:您已经准确地描述了它应该如何工作。每个需要模型参考的控制器都有一个
setModel
方法。如果它有一个嵌套的控制器,也需要访问模型,那么它的