JavaFX - FileChooser window 正在打开,但默认的 initialModality 不工作
JavaFX - The FileChooser window is opening but the default initialModality isn't working
我创建了一个应用程序,我必须在其中单击 MenuItem "Open..." 才能打开 FileChooser。 FileChooser 确实打开了,但问题是我可以单击或关闭第一个 window,而此 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);
}
我的初始化根布局:
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();
}
}
您正在使用 Application
class 作为 FXML 的控制器 class。这是非常混乱的,你应该避免它。
事情是这样的:
- 您启动应用程序。这会导致 FX 工具包被初始化,FX 应用程序线程启动,您的
Application
subclass 实例被创建,Stage
被创建并且 start(...)
在该实例上调用,在 FX 应用程序线程上。
- 您的
start
方法设置了启动序列 创建的实例的primaryStage
字段
- 您创建一个
FXMLLoader
并加载 FXML 文件。
FXMLLoader
创建了控制器 class 的一个实例(恰好是 Application
subclass)。然后它初始化该实例上所有 @FXML
注释的字段,并注册处理程序方法。请注意,primaryStage
字段从未在此实例上初始化。
当用户按下"Open"MenuItem
时,handleOpenMenuItem()
方法在第4步创建的实例(不是第1步创建的实例)上被调用。您创建 FileChooser
,并调用 showOpenDialog(...)
并传入 primaryStage
的值。由于 primaryStage
在这种情况下是 null
,文件选择器没有所有者 window,因此无法实现任何有意义的模态。
要解决此问题,请为您的控制器创建一个单独的 class。您可以通过在场景中的任何节点上调用 getScene().getWindow()
来获取 window。
我创建了一个应用程序,我必须在其中单击 MenuItem "Open..." 才能打开 FileChooser。 FileChooser 确实打开了,但问题是我可以单击或关闭第一个 window,而此 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);
}
我的初始化根布局:
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();
}
}
您正在使用 Application
class 作为 FXML 的控制器 class。这是非常混乱的,你应该避免它。
事情是这样的:
- 您启动应用程序。这会导致 FX 工具包被初始化,FX 应用程序线程启动,您的
Application
subclass 实例被创建,Stage
被创建并且start(...)
在该实例上调用,在 FX 应用程序线程上。 - 您的
start
方法设置了启动序列 创建的实例的 - 您创建一个
FXMLLoader
并加载 FXML 文件。 FXMLLoader
创建了控制器 class 的一个实例(恰好是Application
subclass)。然后它初始化该实例上所有@FXML
注释的字段,并注册处理程序方法。请注意,primaryStage
字段从未在此实例上初始化。
primaryStage
字段
当用户按下"Open"MenuItem
时,handleOpenMenuItem()
方法在第4步创建的实例(不是第1步创建的实例)上被调用。您创建 FileChooser
,并调用 showOpenDialog(...)
并传入 primaryStage
的值。由于 primaryStage
在这种情况下是 null
,文件选择器没有所有者 window,因此无法实现任何有意义的模态。
要解决此问题,请为您的控制器创建一个单独的 class。您可以通过在场景中的任何节点上调用 getScene().getWindow()
来获取 window。