JavaFX - FileChooser窗口正在打开,但默认的initialModality不起作用

时间:2015-04-08 18:23:33

标签: java javafx javafx-8 filechooser

我创建了一个应用程序,我必须点击一个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();
    }
}

1 个答案:

答案 0 :(得分:2)

您正在使用Application类作为FXML的控制器类。这非常令人困惑,你应该避免它。

以下是发生的事情:

  1. 您启动了该应用程序。这会导致FX工具包被初始化,FX应用程序线程将启动,要创建的Application子类的实例,要创建的Stage以及要在其上调用的start(...)例如,在FX应用程序线程上。
  2. 您的start方法设置启动序列创建的实例的primaryStage字段
  3. 您创建FXMLLoader并加载FXML文件。
  4. FXMLLoader创建控制器类的实例(恰好是Application子类)。然后,它初始化该实例上的所有@FXML - 带注释的字段,并注册处理程序方法。请注意,primaryStage字段永远不会在此实例上初始化。
  5. 当用户按下"打开" MenuItem,在步骤4中创建的实例上调用handleOpenMenuItem()方法(不是在步骤1中创建的实例)。您创建FileChooser,并调用showOpenDialog(...)传递primaryStage的值。由于此实例中primaryStagenull,因此文件选择器没有所有者窗口,因此无法实现任何有意义的模态。

    要解决此问题,请为您的控制器创建一个单独的类。您可以通过在场景中的任何节点上调用getScene().getWindow()来获取窗口。