如何从控制器访问 JavaFx 阶段?
How to access a JavaFx Stage from a Controller?
我正在将一个纯 JavaFx 应用程序转换为一个 FXML 应用程序,在该应用程序中,当将所有内容放在一个 class 中时,下面的代码工作正常,其中 Stage 声明和按钮处理程序在单独的 classes。在控制器中,我正在尝试实现一种方法,允许用户选择一个目录并将其存储在一个变量中供以后使用:
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();
}
}
我该如何解决这个问题?我需要以某种方式再次实现该方法,但突然我无法通过该阶段作为参数。
在您的情况下,从处理程序的 ActionEvent
参数获取场景可能最简单:
@FXML
private void handleSourceBrowse(ActionEvent ae) {
Node source = (Node) ae.getSource();
Window theStage = source.getScene().getWindow();
sourceDirectoryChooser.showDialog(theStage);
}
有关更多信息,请参阅 JavaFX: How to get stage from controller during initialization?。不过,我不赞成评分最高的答案,因为它在加载 .fxml
文件后向控制器添加了编译时依赖性(毕竟该问题已标记为 javafx-2
,所以不确定如果上面的方法已经在那里工作,而且问题的上下文看起来有点不同)。
另见 How do I open the JavaFX FileChooser from a controller class?
另一种方法是为舞台定义静态 getter 并访问它
Main Class
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()
在控制器中Class
public class Controller {
public void onMouseClickAction(ActionEvent e) {
Stage s = Main.getPrimaryStage();
s.close();
}
}
我正在将一个纯 JavaFx 应用程序转换为一个 FXML 应用程序,在该应用程序中,当将所有内容放在一个 class 中时,下面的代码工作正常,其中 Stage 声明和按钮处理程序在单独的 classes。在控制器中,我正在尝试实现一种方法,允许用户选择一个目录并将其存储在一个变量中供以后使用:
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();
}
}
我该如何解决这个问题?我需要以某种方式再次实现该方法,但突然我无法通过该阶段作为参数。
在您的情况下,从处理程序的 ActionEvent
参数获取场景可能最简单:
@FXML
private void handleSourceBrowse(ActionEvent ae) {
Node source = (Node) ae.getSource();
Window theStage = source.getScene().getWindow();
sourceDirectoryChooser.showDialog(theStage);
}
有关更多信息,请参阅 JavaFX: How to get stage from controller during initialization?。不过,我不赞成评分最高的答案,因为它在加载 .fxml
文件后向控制器添加了编译时依赖性(毕竟该问题已标记为 javafx-2
,所以不确定如果上面的方法已经在那里工作,而且问题的上下文看起来有点不同)。
另见 How do I open the JavaFX FileChooser from a controller class?
另一种方法是为舞台定义静态 getter 并访问它
Main Class
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()
在控制器中Class
public class Controller {
public void onMouseClickAction(ActionEvent e) {
Stage s = Main.getPrimaryStage();
s.close();
}
}