多个FXML与控制器,共享对象 [英] Multiple FXML with Controllers, share object

查看:310
本文介绍了多个FXML与控制器,共享对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Goodevening everyone,



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



我已经得到了这么远,直到我被困住:



public class Country {
private SimpleStringProperty country = new SimpleStringProperty();

//构造函数
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)。它包含一个边框窗格,顶部面板中有一个菜单栏,中间有一个内容窗格。在初始化时,我创建一个新的Country对象并将其存储在全局变量中。我有一个方法,当单击菜单项时,将另一个FXML加载到内容窗格中:



SampleController.java

  public class SampleController implements可初始化{

@FXML
private Pane pContent;

private国家c;

@FXML
private void handleButtonAction(ActionEvent event)throws IOException {
System.out.println(c); //这打印比利时,这是正确的

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;
}
}



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



Sub1Controller.java

  public class Sub1Controller implements Initializable {

/ **
*初始化控制器类。
* /
@Override
public void initialize(URL url,ResourceBundle rb){
SampleController sp = new SampleController(); //我不知道如何获取原始的SampleController对象
System.out.println(sp.getCountryFromSampleController());
//这打印null,这是逻辑的,因为我创建一个新的SampleController对象。
}
}

我有问题, 'original'SampleController对象,因此我可以使用getCountryFromRoot()方法来获取值为Belgium的Country对象?我一直在这个问题上搜索几个小时,并已阅读关于这个StackOverflow的每一个帖子,但它似乎我找不到丢失的链接...任何帮助(最好用这段代码)是赞赏!



对不起,长期的帖子,我尽可能完整,否则我永远不会理解...

解决方案

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






1。引入模型的一种可能方法是上下文。让我们考虑一个案例,然后你只有一个模型为整个项目,所以你可以有一个全局上下文的形式 Singleton

  public class Context {
private final static Context instance = new Context

public static Context getInstance(){
return instance;
}

private国家国家=新国家();

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。如果你不想有应用程序全局模型,它会工作得更好。所以创建类似的Context类但没有实例字段,并且:

  public class Sub1Controller implements Initializable {
private Context context;
public void setContext(Context context){
this.context = context;
//这里初始化依赖于国家的数据,而不是初始化()
}
}


b $ b

中设置上下文:

 上下文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()));
//这里我们去
((Sub1Controller)fxmlloader.getController())。setContext(currentContext);
}


Goodevening everyone,

I have found a bunch of posts already on this topic but I still can not manage to pass an object from Controller1 to Controller2. Is there somewhere a full tutorial or some example project that does this?

I've gotten this far until I got stuck:

Country 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();
}
}

When the program starts, the main FXML gets loaded (Sample.fxml). This contains a border pane with a menu bar in the top panel and a content pane in the center. On initialize I create a new Country object and store it in a global variable. I have a method that loads another FXML into the content pane when a menu item is clicked:

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;
}
}

Now I wish to capture the Country object when the Sub1.fxml gets loaded, which means I need to fetch the country object on initialize():

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.         
}    
}

The question that I have, how can I get the 'original' SampleController object so I can use the getCountryFromRoot() method to fetch the Country object with value Belgium? I've been searching on this issue for hours and hours and have read every post on StackOverflow about this, but it seems I do not find the missing link... any help (preferably with this code) is appreciated!

Sorry for the long post, I tried to be as complete as possible else I'll never understand...

解决方案

FXML is a simple form of MVC pattern. FXML file is a view, Controller is obvious, what's missed? The model -- a place where you store all data relative to your current view and, thus, which you can use to share Country data between controllers.


1. One of the possible approach to introduce model is "context". Let's consider a case, then you have only one model for the whole project so you can have a global context in a form of Singleton

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;
    }
}

Your SampleController will have next changes:

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

And SubController1 can access it the same way:

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


2. Another way is to pass context to SubController1 then you load it's xml. It will work better if you don't want to have application global model. So create similar Context class but without instance fields, and:

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()
    }
}

Setting context in 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);
}

这篇关于多个FXML与控制器,共享对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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