3

JavaFX2 の新しい世界を学んでいるときに、別の厄介な問題に出くわしました。複数のシーン (~10 シーン) を持つプログラムを開発しています。そのために、次のような小さなクラスを作成しました。

public class SceneSelector {
    ...
    public void setScene(Stage stage, String fxmlfilename, ObservableList ol) throws Exception{
        String s = "../" + fxmlfilename;
        Parent root = FXMLLoader.load(getClass().getResource(s));
        root.setUserData(ol);

        Scene scene = new Scene(root);
        stage.setScene(scene);

        //show the stage
        stage.show();
    }
}

このクラスは、シーンを切り替えるのに十分に機能します。問題は、時々 Scene1 から Scene2 にデータを渡す必要があることです。setUserData()基本的に1つのことを除いて機能する新しいシーンを設定することで、これをやろうとしています。新しいシーンが初期化されているときにユーザーデータを取得するにはどうすればよいですか? (その時点でノードはまだ null であるため)

シーン 1 のコード:

//Code connected to a button that opens the new Scene
private void openLabID(ActionEvent event) throws Exception {       
    final Stage primaryStage = (Stage) btnNewScene.getScene().getWindow();

    ObservableList<Koe> olAfTeWerkenKoeien = DA_Koe.getAfTeWerkenKoeien();
    ss.setScene(primaryStage, "GUI/scenes/koe/Koe.fxml", olAfTeWerkenKoeien);
}

シーン 2 のコード:

public void initialize(URL url, ResourceBundle rb) {
    Scene s = lbl.getScene();
    ObservableList<Koe> olAfTeWerkenKoeien = (ObservableList<Koe>) s.getRoot().getUserData();
    System.out.println(olAfTeWerkenKoeien.size());
} 

もちろん、Scene s はこの時点で null 値を返します (この時点で lbl は null であるため)。

このコードを Scene2 のボタンにアタッチすると、おまじないのように機能しますが、自動的に読み込まれるはずです。

編集: setMyData() メソッドを使用したデータの設定は問題ありませんが、取得は次のとおりです。

public ObservableList<Koe> getMyData() {
   return this.myData;
}

コントローラーの初期化時に CustomScene オブジェクトを取得するにはどうすればよいですか? 以下でこれを行うと NullPointerException が発生するため (btnSluiten がまだ初期化されていないため):

@Override
public void initialize(URL url, ResourceBundle rb) {
    ...
    Stage stage = (Stage) btnSluiten.getScene().getWindow();
    CustomScene cs = (CustomScene) stage.getScene();

    ObservableList<Koe> olKoe = cs.getMyData();

    System.out.println(olKoe.size());
}
4

4 に答える 4

2

シーンを本当に意味のあるものにしたい場合 (別名、特定のユーザー データを保存する) は、シーンを拡張できます。

public class FooScene extends Scene {
   private ObservableList myData;

   public setMyData(ObservableList data) {
       this.myData = data;
       //handle data
   }
}

シーンが自分で呼び出すように初期化した後で、セットアップ コードが確実に呼び出されるようにする最も簡単な方法は次のとおりです。

public class SceneSelector {
    ...
    public void setScene(Stage stage, String fxmlfilename, ObservableList ol) throws Exception{
        String s = "../" + fxmlfilename;
        Parent root = FXMLLoader.load(getClass().getResource(s));

        // first: add root to scene
        FooScene scene = new FooScene(root);
        // second: apply data to scene (or root)
        scene.setMyData(ol);
        stage.setScene(scene);

        //show the stage
        stage.show();
    }
}
于 2012-07-16T23:15:06.173 に答える
2

Scene オブジェクト内のポイントを見逃したと思います。Scene クラスのドキュメントから、次のことがわかります。

JavaFX Scene クラスは、シーン グラフ内のすべてのコンテンツのコンテナです。

つまり、Scene オブジェクトは単なるコンテナーであり、データを保持することは想定されていません。

それを念頭に置いて、次のようなフィールドを持つ別の静的オブジェクトを作成できます

private static Label lbl;

...

public static Label getLbl()
{
    return MyStaticObject.Lbl;
}

...

それを使用してlbl(または情報に合ったオブジェクト)を保存し、静的に取得します。

アプリケーションから他の Stage オブジェクトの所有者を設定するために、これを行っています。お役に立てば幸いです。乾杯

于 2012-07-16T19:26:09.583 に答える
2

シーンにコントローラーを使用し、コントローラーを介してデータを渡すことができます。

String filePath1 =  "../" + fxmlfilename;
URL location1 = YourController1.class.getResource(filePath1);
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location1);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
Parent root = (Node) fxmlLoader.load(location1.openStream());

YourController1 ctrl1 = (YourController1) fxmlLoader.getController();

次に、コントローラーにデータを割り当てることができます。

ctrl1.setUserData();

最後に、必要に応じてシーンを表示します。

Scene scene = new Scene(root);
stage.setScene(scene);

//show the stage
stage.show();

コントローラーの initialize() メソッドでは、通常のデータ オブジェクトとしてコントローラーからデータを取得するだけです。

于 2012-07-30T08:27:59.497 に答える