Program Flashes Upon Opening of Popup Window

Created a full screen application with a popup window opening up upon pressing the ESCAPE key. Once run however the application flashes and then shows the popup window.

    //Pop-up window
    Stage window = new Stage();
    window.initModality(Modality.NONE);
    //Exit Panel
    VBox exitBox = new VBox();
    exitBox.setPadding(new Insets(10));
    Button exitPaneExit = new Button();
    exitPaneExit.setText("Return");
    exitPaneExit.setMinSize(75.0, 30.0);
    exitPaneExit.setOnAction(e -> {
        window.close();
    });
    Button exitButton = new Button();
    exitButton.setText("Exit");
    exitButton.setMinSize(75.0, 30.0);
    exitButton.setOnAction(e -> {
        System.exit(0);
    });
    exitBox.getChildren().addAll(exitPaneExit,exitButton);
    exitBox.setVisible(true);
    Scene scene = new Scene(exitBox);
    window.initStyle(StageStyle.UNDECORATED);
    window.initOwner(primaryStage);
    window.setScene(scene);
    mapScene.setOnKeyPressed(e -> {
        if(e.getCode()==KeyCode.ESCAPE)
        {
            window.show();
        }
    });

The code runs fine and I get no errors however the application flashes upon opening the popup which is QUITE annoying.

Upvotes: 2

Views: 1148

Answers (2)

I finally found the solution myself through the implementation of the Popup class. This is effect is the same as the creation of a transparent/utility stage with an initOwner, but is built into JavaFX. When shown it requires an initOwner so that is the argument I placed there.

Here is the code:

The code relevant to the actual popup.

    private Popup addExitPopup(){
    Popup exitPopup = new Popup();
    //Exit Panel
    VBox exitBox = new VBox();
    exitBox.setPadding(new Insets(10));
    Button exitPaneExit = new Button();
    exitPaneExit.setText("Return");
    exitPaneExit.setMinSize(75.0, 30.0);
    exitPaneExit.setOnAction(e -> {
        exitPopup.hide();
    });
    Button exitButton = new Button();
    exitButton.setText("Exit");
    exitButton.setMinSize(75.0, 30.0);
    exitButton.setOnAction(e -> {
        System.exit(0);
    });
    exitBox.getChildren().addAll(exitPaneExit,exitButton);
    exitBox.setVisible(true);

    exitPopup.setAutoHide(true);
    exitPopup.getContent().add(exitBox);
    return exitPopup;
}

The code relevant to making it appear in a full screen application.

    @Override
public void start(Stage primaryStage) throws Exception {
    Popup exitPopupO = addExitPopup();
    AnchorPane mapAnchorO = addMapAnchor();
    Scene mapScene = new Scene(mapAnchorO);
    primaryStage.setScene(mapScene);
    primaryStage.setFullScreen(true);
    primaryStage.setResizable(false);
    primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
    primaryStage.show();

    mapScene.setOnKeyPressed(e -> {
        if(e.getCode()==KeyCode.ESCAPE)
        {
            exitPopupO.show(primaryStage);
        }
    });
}

Upvotes: 0

Maglioni Lorenzo
Maglioni Lorenzo

Reputation: 378

Why do you need to create an other stage? Can't you use a simple custom dialog like this?

Dialog window = new Dialog();
window.setTitle("Your title");
window.setHeaderText("Your header");
window.setContentText("Your Content Text")
window(Modality.APPLICATION_MODAL);
window(mainStage);
window(StageStyle.UTILITY);
ButtonType btnReturn = new ButtonType("return");
ButtonType btnExit = new ButtonType("exit");
window.getDialogPane().getButtonTypes().addAll(btnReturn, btnExit);
mapScene.setOnKeyPressed(e -> {
    if(e.getCode()==KeyCode.ESCAPE){
        Optional<ButtonType> result = window.showAndWait();
        if (result.get() == btnExit){
            Platform.exit();
            System.exit(0);
        }
    }
});

I passed the stage from the the class with the main method to the controller, so it shouldn't generate any exception, like this:

main class:

public void start(Stage stage) throws Exception {

    FXMLLoader loader = new FXMLLoader(getClass().getResource("ToolConfiguration.fxml"));

    Parent root = (Parent)loader.load();

    ToolConfigurationController controller = loader.<ToolConfigurationController>getController();
    controller.setLanguage("en", stage);

    notifier = Notification.Notifier.INSTANCE;
    [...]
}

It works fine for me

and comes like this in the controller class:

public void setLanguage(String language, Stage stage){
    this.mainStage = stage;
    this.language=language;

    locale = new Locale(language.toLowerCase(), language);
    bundle = ResourceBundle.getBundle("smartDrawerTool.bundles.ToolConfiguration", locale);
}

Upvotes: 1

Related Questions