JavaFX - 添加ScrollPane弹出窗口,当用户单击它时关闭该弹出窗口

时间:2016-06-13 06:47:32

标签: java user-interface javafx

我的标题措辞严厉,因为我的问题很难描述,所以我为它绘制了一个图像:

enter image description here

我有一个ImageView对象,代表一堆牌(不是扑克牌,但只是用它们作为例子)。单击此图像视图时,我需要一个弹出窗口,其中包含ScrollPane并向其显示链接列表中的所有卡对象。当用户单击窗口外的任何位置(稍后点击鼠标右键)时,需要关闭滚动窗格窗口。

我已经尝试过的方法:

  • 使用APPLICATION_MODAL的场景。然后做了Scene.showAndWait()。我不喜欢这种方法,因为它在用户的任务栏上创建了另一个应用程序。它也感觉笨重而且很糟糕。

  • 将我的根窗格更改为StackPane,然后在用户点击套牌时将此Scrollpane添加到堆栈窗格。这出于某种原因非常缓慢,看起来非常突兀。这也很烦人,因为我的备用类需要访问根窗格(因为当它关闭时,它需要转到根StackPane并自己调用.remove())。

还有其他更好的方法来实现这一目标吗?我的应用程序将拥有许多这样的堆,所以这个框架需要很好地工作。

2 个答案:

答案 0 :(得分:2)

我仍然建议开设一个新的Stage,但有一些限制可以通过这种方法解决您的问题。

您可以使用Stage的{​​{3}}属性将另一个Stage作为所有者,因此任务栏上不会显示其他图标。

您可以将initOwner属性与initStyleTRANSPARENT StageStlye一起使用,这样可确保只显示内容。

最后,您可以使用UNDECORATED检查Stage是否失去了关闭它的重点。

示例

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,400,400);

            Button b = new Button("Open deck");
            b.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    Stage popupStage = new Stage();

                    popupStage.initOwner(primaryStage);
                    popupStage.initStyle(StageStyle.UNDECORATED);
                    Scene sc = new Scene(new ScrollPane(), 300, 300);
                    popupStage.setScene(sc);

                    popupStage.focusedProperty().addListener(new ChangeListener<Boolean>() {

                        @Override
                        public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
                                Boolean newValue) {
                            if(!newValue)
                                popupStage.close();

                        }
                    });

                    popupStage.show();

                }
            });

            root.setCenter(b);


            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

当然也可以不在新的Stage中打开它,而是在当前ScrollPane内绘制Stage 重叠的内容Stage使用例如focusedPropertyAnchorPane作为root,但第一个解决方案的优势在于您没有绑定主Stage的维度(弹出窗口可以有你想要的任何尺寸。)

答案 1 :(得分:0)

您可以使用捕获鼠标事件的低级系统挂钩来实现此目的。

http://kra.lc/blog/2016/02/java-global-system-hook/https://github.com/kwhat/jnativehook/releases

我希望这就是你所需要的,否则我的问题就会出错。