我创建了一个应用程序,我必须点击一个MenuItem"打开......"打开FileChooser。 FileChooser确实打开了,但问题是当FileChooser仍然打开时我可以点击或关闭第一个窗口。
我的代码有问题吗?将primaryStage
作为参数添加到fileChooser.showOpenDialog(primaryStage);
是错误的吗?
这些是我的声明
private Stage primaryStage;
这是我的开始方法。
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
primaryStage.setTitle("Ontology - Language Disorders");
primaryStage.centerOnScreen();
initRootLayout();
showOntologyOverview();
primaryStage.show();
}
这是我的OpenDialog
@FXML
private void handleOpenMenuItem(ActionEvent event){
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("OWL (*.owl)", "*.owl"));
fileChooser.showOpenDialog(primaryStage);
}
我的initRootLayout:
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
答案 0 :(得分:2)
您正在使用Application
类作为FXML的控制器类。这非常令人困惑,你应该避免它。
以下是发生的事情:
Application
子类的实例,要创建的Stage
以及要在其上调用的start(...)
例如,在FX应用程序线程上。start
方法设置启动序列创建的实例的primaryStage
字段FXMLLoader
并加载FXML文件。FXMLLoader
创建控制器类的实例(恰好是Application
子类)。然后,它初始化该实例上的所有@FXML
- 带注释的字段,并注册处理程序方法。请注意,primaryStage
字段永远不会在此实例上初始化。当用户按下"打开" MenuItem
,在步骤4中创建的实例上调用handleOpenMenuItem()
方法(不是在步骤1中创建的实例)。您创建FileChooser
,并调用showOpenDialog(...)
传递primaryStage
的值。由于此实例中primaryStage
为null
,因此文件选择器没有所有者窗口,因此无法实现任何有意义的模态。
要解决此问题,请为您的控制器创建一个单独的类。您可以通过在场景中的任何节点上调用getScene().getWindow()
来获取窗口。