Mohamed Benmahdjoub
Mohamed Benmahdjoub

Reputation: 1280

JavaFX - The FileChooser window is opening but the default initialModality isn't working

I created an application, in which i have to click on a MenuItem "Open..." to open a FileChooser. The FileChooser do open, but the problem is that i can click or close the first window while this FileChooser is is still opened.

Do i have a problem in my code ? Is it wrong to put primaryStage as a parameter to fileChooser.showOpenDialog(primaryStage); ?

These are my declarations

private Stage primaryStage;

This is my start method.

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    primaryStage.setTitle("Ontology - Language Disorders");
    primaryStage.centerOnScreen();
    initRootLayout();
    showOntologyOverview();
    primaryStage.show();
}

This is my 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);
}

My 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();
    }
}

Upvotes: 2

Views: 999

Answers (1)

James_D
James_D

Reputation: 209340

You are using the Application class as the controller class for your FXML. This is highly confusing and you should avoid it.

Here is what happens:

  1. You launch the application. This causes the FX toolkit to be initialized, the FX Application Thread to start, an instance of your Application subclass to be created, a Stage to be created and start(...) to be invoked on that instance, on the FX Application Thread.
  2. Your start method sets the primaryStage field of the instance created by the startup sequence
  3. You create an FXMLLoader and load the FXML file.
  4. The FXMLLoader creates an instance of the controller class (which happens to be the Application subclass). It then initializes all @FXML-annotated fields on that instance, and registers handler methods. Note that the primaryStage field is never initialized on this instance.

When the user presses the "Open" MenuItem, the handleOpenMenuItem() method is invoked on the instance created in step 4 (not the instance created in step 1). You create the FileChooser, and call showOpenDialog(...) passing in the value of primaryStage. Since primaryStage is null in this instance, the file chooser has no owner window, and so cannot implement any meaningful modality.

To fix this, create a separate class for your controller. You can get the window by calling getScene().getWindow() on any node in the scene.

Upvotes: 2

Related Questions