如何从Controller访问JavaFx Stage?

Sar*_*on1 7 java controller javafx fxml

我正在转换一个纯JavaFx应用程序,其中下面的代码在将所有内容放在一个类中时工作正常,到FXML,其中Stage声明和按钮处理程序在不同的类中.在一个Controller中,我试图实现一个方法,允许用户选择一个目录并将其存储在一个变量中供以后使用:

private File sourceFile;
DirectoryChooser sourceDirectoryChooser;

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

但是,"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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么绕过这个?我需要以某种方式再次实现该方法,但突然间我不能将该阶段作为参数传递.

And*_*ter 21

在您的情况下,从ActionEvent处理程序的参数获取场景可能最简单:

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

    sourceDirectoryChooser.showDialog(theStage);
}
Run Code Online (Sandbox Code Playgroud)

请参阅JavaFX:如何在初始化期间从控制器获取阶段?了解更多信息.我并不赞成最高级别的答案,因为它在.fxml文件加载后向控制器添加了编译时依赖性(在所有问题被标记之后javafx-2,所以不确定上述方法是否已在那里工作,并且问题的背景看起来有点不同).

另请参阅如何从控制器类中打开JavaFX FileChooser?


Jin*_*P C 7

另一种方法是为舞台定义一个静态 getter 并访问它

主类

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以通过调用访问此阶段

Main.getPrimaryStage()

在控制器类中

public class Controller {
public void onMouseClickAction(ActionEvent e) {
    Stage s = Main.getPrimaryStage();
    s.close();
}
}
Run Code Online (Sandbox Code Playgroud)

  • 非常好的解决方案,但这里的 getter 和 setter 应该是静态的。 (2认同)