Uitableview Javafx从另一个FXML更新tableview
参考文章 我有接口1 FXML,如下所示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
<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
方法。如果它有一个嵌套的控制器,也需要访问模型,那么它的