JavaFX popup hidden when stage is in fullscreen mo

2019-05-22 18:09发布

问题:

I am trying to popup a dialog over my fullscreen primary stage in javafx. When I create my popup, it is unexpectedly hidden behind my fullscreen primary stage until the stage is removed from fullscreen mode (via ESC). If I make my primary stage maximized and undecorated instead of fullscreen, then my popup will appear on top of the primary stage as expected.

Am I missing something about how fullscreen mode is different than maximized and undecorated mode? Am I using fullscreen mode improperly?

I am using java version 1.8.0_20 on CentOS 6.5 with Gnome.

Here is my SSCCE:

import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.stage.*;

public class TestApplication extends Application {
    private Stage primaryStage;

    public static void main(String[] arguments) {
        launch(arguments);
    }

    public void start(Stage stage) {
        this.primaryStage = stage;

        // Create a fullscreen primary stage.    
        primaryStage.setTitle("Main Stage");
        primaryStage.setScene(new Scene(createRoot()));
        primaryStage.setFullScreen(true);

        primaryStage.show();
    }       

    private Parent createRoot() {
        Button button = new Button("Show popup");
        button.setOnAction((event) -> showPopup());

        return button;
    }

    private void showPopup() {
        // Create a popup that should be on top of the primary stage.
        Stage popupStage = new Stage();

        popupStage.setScene(new Scene(createPopupRoot()));
        popupStage.setTitle("Popup Stage");
        popupStage.initModality(Modality.WINDOW_MODAL);
        popupStage.initOwner(primaryStage);

        popupStage.show();
    }

    private Parent createPopupRoot() {
        return new Label("This is a popup!");
    }
}

回答1:

Assuming you're on a Mac, this is a known issue, which is fixed in 8u40. You may need to use the ea version until the full release.

The basic history of this bug is that JavaFX implemented its own full screen implementation, in order to support OS X versions prior to 10.7 (which didn't have a native full-screen mode). That implementation uses an "exclusive mode", which prevents other windows from showing. This can get pretty bad: for example ComboBoxs won't work... The issue is fixed in 8u40 by using the native mode (since OS X versions prior to 10.7 are no longer supported anyway).

Note that if you don't programmatically set full screen mode, and allow the user to go to full screen using the Mac OS button on the window title bar, then the issue should not arise.



回答2:

After repeating this problem with java version '1.8.0_40', I finally found how to fix this problem!

popupStage.initStyle(StageStyle.UTILITY);

Stage.initStyle(StageStyle) -- JavaFX 8

Giving the popup a style of StageStyle.UTILITY seems to keep the popup in front of the fullscreen window even when clicking outside of the popup.

I saw this same issue when using the new Alert class in java 1.8.0_40, and setting the style to StageStyle.UTILITY fixed that as well (Dialog.initStyle(StageStyle) -- JavaFX 8).

I don't know why this works.

Side Note:

It looks like removing the call to popupStage.initOwner(...) allows the popup to appear above the full screen application, but clicking outside of the popup causes the popup to disappear.