在javafx中显示工具提示会将其舞台置于前台

Sel*_*lim 15 java javafx

我正在尝试解决jdk中的这个错误:http://bugs.java.com/bugdatabase/view_bug.do? video_id = 8088624

public class Blubb extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button btn = new Button("Click");
        btn.setTooltip(new Tooltip("Blubb"));

        Scene scene = new Scene(new BorderPane(btn), 320, 240);
        primaryStage.setScene(scene);
        primaryStage.show();

        Stage secondStage = new Stage();
        secondStage.setScene(new Scene(new BorderPane(new Button("Click")), 320, 240));
        //secondStage.initOwner(primaryStage);
        secondStage.show();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果主舞台上的按钮悬停,它将出现在第二阶段的前面.我发现调用initOwner()一个舞台将消除这种行为.

现在我的问题是:我有多个"弹出窗口",它们有一个共同的所有者(主要阶段).将鼠标悬停在主阶段上的控件上后,在initOwner()解决方法后不会导致任何意外行为.然而,如果您将鼠标悬停在弹出窗口中的控件上而另一个弹出窗口处于焦点位置,则悬停的弹出窗口将会隐藏焦点.

有没有办法可以解决这个错误,不仅是初级阶段,还有弹出窗口?

更新:结果我的解决方法有不良副作用.舞台状态的Javadocs如下:

舞台将始终位于其父窗口的顶部.

另外,什么是一种解决方法,使弹出窗口不"总是在顶部"和最小化?

Mat*_*ght 4

有一种方法可以通过覆盖 StackPanes 来解决这个问题。创建Scene一个,以便在舞台失去焦点时StackPane添加另一个。StackPane当窗格未处于焦点状态时,覆盖的窗格将防止Tooltip鼠标悬停时发生 s 或任何其他情况。您还可以最小化任何阶段,并且它们不会始终位于顶部。

public class Blubb extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button button_1 = new Button("Button #1");
        button_1.setTooltip(new Tooltip("Blubb #1"));

        StackPane primary = new StackPane(new BorderPane(button_1));
        primaryStage.setScene(new Scene(primary, 320, 240));
        addStageFocusListener(primaryStage, primary);
        primaryStage.show();

        Button button_2 = new Button("Button #2");
        button_2.setTooltip(new Tooltip("Blubb #2"));

        StackPane second = new StackPane(new BorderPane(button_2));
        Stage secondStage = new Stage();
        addStageFocusListener(secondStage, second);
        secondStage.setScene(new Scene(second, 320, 240));
        secondStage.show();
    }

    public void addStageFocusListener(Stage stage, StackPane stackPane) {
        stage.focusedProperty().addListener(new ChangeListener<Boolean>(){
            public final StackPane preventTooltip = new StackPane();
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                if(stage.isFocused()) {
                    if(stackPane.getChildren().contains(preventTooltip)) {
                        stackPane.getChildren().remove(preventTooltip);
                    }
                } else {
                    stackPane.getChildren().add(preventTooltip);
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)