多个FXML与控制器共享对象

各位晚上好,

我已经find了一堆已经在这个主题上的post,但我仍然无法设法将一个对象从Controller1传递给Controller2。 有没有完整的教程或一些示例项目,这样做?

我已经得到了很多,直到我陷入困境:

国家class

public class Country { private SimpleStringProperty country = new SimpleStringProperty(""); //Constructor public Country() { } //GETTERS public String getCountry() { return country.get(); } //SETTERS public void setCountry(String value) { country.set(value); } @Override public String toString() { return getCountry(); } } 

当程序启动时,主FXML被加载(Sample.fxml)。 这包含一个边框窗格,顶部面板中有一个菜单栏,中间有一个内容窗格。 初始化时,我创build一个新的Country对象并将其存储在一个全局variables中。 我有一个方法,当点击一个菜单项时,将另一个FXML加载到内容窗格中:

SampleController.java

 public class SampleController implements Initializable { @FXML private Pane pContent; private Country c; @FXML private void handleButtonAction(ActionEvent event) throws IOException { System.out.println(c); //this prints Belgium, which is correct URL url = getClass().getResource("Sub1.fxml"); FXMLLoader fxmlloader = new FXMLLoader(); fxmlloader.setLocation(url); fxmlloader.setBuilderFactory(new JavaFXBuilderFactory()); pContent.getChildren().clear(); pContent.getChildren().add((Node) fxmlloader.load(url.openStream())); } @Override public void initialize(URL url, ResourceBundle rb) { c = new Country(); c.setCountry("Belgium"); } public Country getCountryFromSampleController(){ return c; } } 

现在我希望在Sub1.fxml被加载时捕获Country对象,这意味着我需要在initialize()上获取country对象:

Sub1Controller.java

 public class Sub1Controller implements Initializable { /** * Initializes the controller class. */ @Override public void initialize(URL url, ResourceBundle rb) { SampleController sp = new SampleController(); //I don't know how to fetch the original SampleController object System.out.println(sp.getCountryFromSampleController()); //this prints null, which is ofcourse logical because I make a new SampleController object. } } 

我有这个问题,我怎样才能得到'原始的'SampleController对象,所以我可以使用getCountryFromRoot()方法来获取值比利时国家对象? 我一直在这个问题上search几个小时,并阅读每一个关于这个StackOverflow的post,但似乎我没有find缺less的链接…任何帮助(最好与此代码)是赞赏!

对不起,长的职位,我试图尽可能完整,否则我永远不会明白…

FXML是一种简单的MVC模式 。 FXML文件是一个视图,Controller是显而易见的,什么错过了? 模型 – 您可以在其中存储与当前视图有关的所有数据,从而可以在控制器之间共享国家/地区数据。


1.引入模型的可能方法之一是“背景”。 让我们考虑一个案例,那么你只有一个模型的整个项目,所以你可以有一个单一的forms的全球上下文

 public class Context { private final static Context instance = new Context(); public static Context getInstance() { return instance; } private Country country = new Country(); public Country currentCountry() { return country; } } 

您的SampleController将有下一个变化:

 @Override public void initialize(URL url, ResourceBundle rb) { Context.getInstance().currentCountry().setCountry("Belgium"); } 

SubController1可以以同样的方式访问它:

 @Override public void initialize(URL url, ResourceBundle rb) { System.out.println(Context.getInstance().currentCountry().getCountry()); } 

2.另一种方法是将上下文传递给SubController1然后加载它的xml。 如果你不想拥有应用程序的全球模式,它会更好。 所以创build类似的Context类但没有实例字段,并且:

 public class Sub1Controller implements Initializable { private Context context; public void setContext(Context context) { this.context = context; // initialize country dependent data here rather then in initialize() } } 

SampleController设置上下文:

 Context currentContext = new Context(); @Override public void initialize(URL url, ResourceBundle rb) { currentContext.currentCountry().setCountry("Belgium"); } @FXML private void handleButtonAction(ActionEvent event) throws IOException { URL url = getClass().getResource("Sub1.fxml"); FXMLLoader fxmlloader = new FXMLLoader(); fxmlloader.setLocation(url); fxmlloader.setBuilderFactory(new JavaFXBuilderFactory()); pContent.getChildren().clear(); pContent.getChildren().add((Node) fxmlloader.load(url.openStream())); // here we go ((Sub1Controller)fxmlloader.getController()).setContext(currentContext); }