web-dev-qa-db-ja.com

コントローラからJavaFxステージにアクセスする方法は?

以下のコードがすべて1つのクラスに入れられたときに正常に機能する純粋なJavaFxアプリを、Stage宣言とボタンハンドラーが別々のクラスにあるFXMLアプリに変換しています。コントローラーで、ユーザーがディレクトリを選択し、後で使用できるように変数に格納できるようにするメソッドを実装しようとしています。

private File sourceFile;
DirectoryChooser sourceDirectoryChooser;

@FXML
private void handleSourceBrowse() {
        sourceDirectoryChooser.setTitle("Choose the source folder");
        sourceFile = sourceDirectoryChooser.showDialog(theStage);
}

ただし、メソッドが必要とするステージである「theStage」は、FolderSyncer4.Javaにのみ存在します(それが正しい用語である場合)。

public class FolderSyncer4 extends Application {

    final String FOLDER_SYNCER = "FolderSyncer";

    Stage theStage;

    @Override
    public void start(Stage primaryStage) throws Exception {
        theStage = primaryStage;

        //TODO do the FXML stuff, hope this works
        Parent root = FXMLLoader.load(getClass().getResource("FolderSyncerMainWindow.fxml"));
        theStage.setScene(new Scene(root, 685, 550));
        theStage.setTitle(FOLDER_SYNCER);
        theStage.show();
    }
}

これを回避するにはどうすればよいですか?どういうわけか、そのメソッドを再度実装する必要がありますが、突然、引数としてステージを通過できなくなりました。

7
Sargon1

あなたの状況では、ハンドラーのActionEventパラメーターからシーンを取得するのがおそらく最も簡単です。

@FXML
private void handleSourceBrowse(ActionEvent ae) {
    Node source = (Node) ae.getSource();
    Window theStage = source.getScene().getWindow();

    sourceDirectoryChooser.showDialog(theStage);
}

詳細については、 JavaFX:初期化中にコントローラーからステージを取得する方法? を参照してください。ただし、.fxmlファイルがロードされた後(すべての質問がjavafx-2でタグ付けされた後)、コンパイル時の依存関係がコントローラーに追加されるため、最高評価の回答には賛成できません。上記のアプローチがすでにそこで機能していて、質問のコンテキストも少し異なっている場合)。

参照 コントローラークラスからJavaFX FileChooserを開くにはどうすればよいですか?

21
Andreas Fester

別の方法は、ステージの静的ゲッターを定義してアクセスすることです。

メインクラス

public class Main extends Application {
    private static Stage primaryStage; // **Declare static Stage**

    private void setPrimaryStage(Stage stage) {
        Main.primaryStage = stage;
    }

    static public Stage getPrimaryStage() {
        return Main.primaryStage;
    }

    @Override
    public void start(Stage primaryStage) throws Exception{
        setPrimaryStage(primaryStage); // **Set the Stage**
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }
}

これで、電話してこのステージにアクセスできます

Main.getPrimaryStage()

コントローラクラス内

public class Controller {
public void onMouseClickAction(ActionEvent e) {
    Stage s = Main.getPrimaryStage();
    s.close();
}
}
3
Jinu P C