0
votes

I'm developing a GUI application using Java8 and JavaFX. The main window has a button that should open new window (with it's own fxml). So far I've been loading the fxml each time the button was pressed but since the new window has tons of controls it (surprisingly) takes some time (aprox 0.5-1s) to open the popup, and thus I've changed the code so that the main controller loads the popup fxml in it's initialize method and whenever the button is clicked the pre loaded window is just shown. It all works good but now I can't set the initOwner(...) on the new window since I don't have access to the window object in the initilize method. I know I don't have to set the initOwner, but then I have two application windows on the start menu (which I want to avoid). Any ideas how to go around this issue? Also, what is the standard way of showing new windows/dialogs in JavaFX, should i load an fxml each time an event occurs or just show/hide the preloaded one?

2

2 Answers

2
votes

You could load the FXML once in the initialize() method, then lazily initialize the dialog window when you need it. I.e.

public class Controller {

    private Parent dialogPane ;
    private Stage dialog ;

    @FXML
    private Button button ;

    public void initialize() throws IOException {
        dialogPane = FXMLLoader.load(getClass().getResource("dialog.fxml"));
    }

    @FXML
    private void handleButtonPress() {
        getDialog().show();
    }

    private Stage getDialog() {
        if (dialog == null) {
            Scene scene = new Scene(dialogPane);
            dialog = new Stage();
            dialog.setScene(scene);
            dialog.initOwner(button.getScene().getWindow());
        }
        return dialog ;
    }
}
0
votes

You can lazy load the fxml. Namely not when app starts or not on every button click, but when it is requested:

private Parent popupPane;
private PopupPaneController popupPaneController;

private void openPopup( ActionEvent event ) {
    if (popupPane == null) {
        popupPane = FXMLLoader.load(...);
        popupPaneController = // get it from FXMLLoader. Search this site for how
    }
    popupPaneController.updatePopupContent(newVals);
    Stage popup = new Stage();
    popup.initOwner(primaryStage);
    stage.setScene(new ScrollPane(popupPane));
    stage.show();
}

Note that if you cache the content of popup window, you can set initOwner() later. Also checkout the Alert class as an alternative for popup. See examples of it.

While showing the preloaded scene/window you may need to update the data shown in the popup. for this implement an updatePopupContent(newVals) method in popup controller's class, and call it on every button click as in code above.