0

I'm having a JavaFX-GUI that enables the user to scan. This process is taking a while. So the user should neither keep clicking around, nor should anyone think the program hung itself.

My solution was a modal window that is just in front of the whole GUI and and disappears itself when everything is finished.

The interface consists of a FXML-Controller, the FXML-File and the MainApp.

So far I'm calling it in the Controller:

Stage stage = Messages.beforeScan(event);    
s.scan(filename);
stage.close();

The beforeScan-Method looks like that (Taken from How to create a modal window in JavaFX 2.1 ):

public static Stage beforeScan(Event event) {
        Stage stage = new Stage(); 
        try {

            Parent root = FXMLLoader.load(
                    FXMLController.class.getResource("/fxml/Scene.fxml"));
            stage.setScene(new Scene(root));
            stage.setTitle("My modal window");
            stage.initModality(Modality.WINDOW_MODAL);
            stage.initOwner(((Node)event.getSource()).getScene().getWindow());
            stage.show();
        } catch (IOException ex) {
            Logger.getLogger(Meldungen.class.getName()).log(Level.SEVERE, null, ex);
        }
        return stage;
    }

Yet this is not successful. If I comment out stage.close(); I can still use my main GUI. So a different approach: Instead of importing the Scene from the controller I tired to obtain it from the MainApp-Class:

public static Stage beforeScan(Event event) {
        Stage stage = new Stage();

            stage.setScene(MainApp.getStage.getScene());
            stage.setTitle("My modal window");
            stage.initModality(Modality.WINDOW_MODAL);
            stage.initOwner(((Node) event.getSource()).getScene().getWindow());
            stage.show();

        return stage;
    }

But this just crashes everything with a StackOverflow. The Popup (Taken from the example here ) is not helpful either. It is even only opened after the scan.

Using an Alert seemed like a good idea, but doing it that way is not only locking the screen but the program itself:

public Alert beforeScan(Event event) {
       javafx.scene.control.Alert alert = new Alert(Alert.AlertType.NONE, "Scan in progress");

       alert.showAndWait();
       return alert;
    }

How should a screen-locking modal window/popup be done properly?

Qohelet
  • 1,459
  • 4
  • 24
  • 41
  • Either you're modifying the UI in from a thread other than the application thread or you're running a long-running task on the application thread blocking it. Either way you're doing it wrong... – fabian Jun 16 '17 at 22:13
  • @fabian - any suggestions what I _should_ do? – Qohelet Jun 16 '17 at 22:14
  • Show the stage, run the long-running task on a different thread and at the end of it use `Platform.runLater` to close the stage... – fabian Jun 16 '17 at 22:16
  • @fabian - frankly I don't get the part with the `Platform.runLater`. I made Scan runnable and used `Thread thread = new Thread(s); thread.start(); thread.join();` Before that I start the dialog and after it I close it. How should the `runLater` be implemented? And how do I make sure the GUI is locked? – Qohelet Jun 16 '17 at 23:32
  • Why do you even start a new thread if you call `join` immediately? I thought of something like this: `stage.show(); new Thread(() -> { try { Thread.sleep(3000); } catch (InterruptedException ex) {} Platform.runLater(stage::close); }).start();` (Replace `Thread.sleep()`+`try-catch` with your long running task.) – fabian Jun 17 '17 at 07:18

0 Answers0