0

開いているアプリ ウィンドウ間でパラメーターを渡すためのトリッキーな (ばかげた mb?) アルゴリズムを作成しようとしています。私がやっていること:

  1. 必要なフィールドを持つクラスを展開するペインがあります。「門」になります。
  2. コントローラーを呼び出すと、ノード ツリーが FXML から読み込まれ、子として「ゲート」オブジェクトにアタッチされます。
  3. 次に、「gate」をルート ノードとして新しいシーンを作成して表示します。
  4. 新しいウィンドウ コントローラーには FXML ルート ノード (「ゲート」の直接の子) への参照があり、「ゲート」を取得するために .getParent() を使用するだけです。

しかし、なんと!nullを返します!私は何を間違っていますか?FXMLLoader を介して別のコントローラーを設定する必要がありますか?

また、あるコントローラーから別のコントローラーへのメッセージ ストリームを整理する正しい方法は何でしょうか?

コードチャンクは次のとおりです。メインアプリクラス:

private void handleMenuVisibility(ActionEvent event) throws IOException
{
    Parent root = FXMLLoader.load(getClass().getResource("/ContextMenus/Visibility.fxml"));
    final AttributedWrapper aw = new AttributedWrapper();
    aw.getChildren().add(root);
    Scene scene = new Scene(aw);
    Stage stage = new Stage();
    stage.setScene(scene);
    stage.show();
}

および呼び出されたウィンドウ コントローラー:

public void initialize(URL url, ResourceBundle rb) {
AttributedWrapper aw = (AttributedWrapper) anchorPane.getParent();
}

upd: AttributedWrapper は javafx.scene.layout.Pane を拡張するクラスです

主要な更新: ここにいくつかの情報が見つかりました: FXML Controller1 で作成されたオブジェクトを内部 FXML コントロールの Controller2 に渡す方法 FXML ファイルのルート ノードとして attributedWrapper を使用すると、一般的に機能します。ただし、呼び出されたコントローラーの初期化に問題が残ります。メイン アプリ コントローラーから呼び出されたコントローラーに送信したパラメーターは使用できません。関数

    public void initialize(URL url, ResourceBundle rb)

FXMLLoader.load() が実行されたときと、データをラッパーに入れる前に正確に開始します。

ここに必需品があります: メインアプリ

final AttributedWrapper aw = FXMLLoader.load(getClass().getResource("/ContextMenus/Visibility.fxml"));
Scene scene = new Scene(aw);
Stage stage = new Stage();
stage.setScene(scene);
    aw.writeParam("key1", "value1");
    stage.show()

呼び出されたコントローラー

@FXML private AttributedWrapper aw;
public void initialize(URL url, ResourceBundle rb) {
System.out.println(aw.readParam("key1"));
anchorPane.writeParam("key2", "value2");
}

呼び出されたウィンドウを閉じた後、「key2」パラメータを読み取って問題ありませんが、呼び出されたウィンドウから「key1」を読み取るとnullが返されます。

ここでパラメータを渡す正しい方法は何ですか? それとも、静的フィールドを作成することしかできませんか?

4

1 に答える 1

1

問題は、public void initialize(URL url, ResourceBundle rb)FXMLLoader 呼び出し中にメソッドが呼び出されていることです。

Parent root = FXMLLoader.load(getClass().getResource("/ContextMenus/Visibility.fxml"));

したがって、親はまだ設定されていません。

それを解決するためにいくつかのアプローチがあります:

  1. 初期化ロジックを別のメソッドに移動し、手動で呼び出します。

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/ContextMenus/Visibility.fxml"));
    Parent root = fxmlLoader.load();
    controller = (MyController) fxmlLoader.getController();
    final AttributedWrapper aw = new AttributedWrapper();
    aw.getChildren().add(root);
    controller.doMyInit();
    
  2. 「メジャーアップ」アプローチを使用しますが、パラメータを設定した後にカスタム init を呼び出します。

  3. にリスナーを追加しanchorPane.parentProperty()て初期化すると、親は not になりましたnull

    root.parentProperty().addListener(new ChangeListener<Parent>() {
    
        @Override
        public void changed(ObservableValue<? extends Parent> ov, Parent oldP, Parent newP) {
            if (newP != null && oldP == null) {
                System.out.println("my parent is " + newP);
            }
        }
    });
    
于 2012-10-05T10:25:45.500 に答える