29

皆さん、こんばんわ、

このトピックに関する投稿をすでにたくさん見つけましたが、それでもController1からController2にオブジェクトを渡すことができません。これを行う完全なチュートリアルまたはサンプルプロジェクトはどこかにありますか?

私は立ち往生するまでこれまでに到達しました:

カントリークラス

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)。これには、上部パネルにメニューバーがあり、中央にコンテンツペインがある境界ペインが含まれています。初期化時に、新しいCountryオブジェクトを作成し、それをグローバル変数に格納します。メニュー項目がクリックされたときに別の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.         
}    
}

私が持っている質問は、getCountryFromRoot()メソッドを使用して値BelgiumでCountryオブジェクトをフェッチできるように、「元の」SampleControllerオブジェクトを取得するにはどうすればよいですか?私はこの問題を何時間も検索していて、これに関するStackOverflowのすべての投稿を読んでいますが、不足しているリンクが見つからないようです...(できればこのコードで)助けていただければ幸いです!

長い投稿で申し訳ありませんが、私は可能な限り完全にしようとしました、そうでなければ私は決して理解できません...

4

2 に答える 2

53

FXMLは、MVCパターンの単純な形式です。FXMLファイルはビューです、コントローラーは明らかです、何が欠けていますか?モデル-現在のビューに関連するすべてのデータを保存する場所であり、したがって、コントローラー間で国データを共有するために使用できます。


1.モデルを導入するための可能なアプローチの1つは、「コンテキスト」です。ケースを考えてみましょう。プロジェクト全体でモデルが1つしかないため、シングルトンの形式でグローバルコンテキストを使用できます。

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をロードすることです。アプリケーションのグローバルモデルが必要ない場合は、より適切に機能します。したがって、同様の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);
}
于 2012-08-28T21:41:40.877 に答える
3

DataFXのFlowAPIを使用すると、CDIを使用してコントローラーインスタンスにデータを挿入できます。

于 2014-03-27T18:29:19.340 に答える