多个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); }
通过使用DataFX的Flow API,您可以使用CDI在控制器实例中注入数据: