有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javajavafx添加了一个滚动窗格弹出窗口,当用户点击弹出窗口时关闭

我的标题措辞糟糕,因为我的问题很难描述,所以我为它画了一幅图:

enter image description here

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

我已经尝试过的方法:

  • 具有应用程序的场景。然后是那个场景。show和wait()。我不喜欢这个方法,因为它在用户的任务栏上创建了另一个应用程序。它也感觉笨重和糟糕

  • 将我的根窗格更改为StackPane,然后在用户单击甲板时将此滚动窗格添加到StackPane。出于某种原因,这是非常缓慢,似乎真的很突兀。这也很烦人,因为我的备用类需要访问根窗格(因为当它关闭时,它需要转到根堆栈窗格并对自身调用.remove()

有没有其他更好的方法来实现这一点?我的应用程序将有许多这样的桩,所以这个框架需要工作得很好


共 (2) 个答案

  1. # 1 楼答案

    我仍然建议开设一个新的Stage,但有一些限制,用这种方法来解决您的问题

    您可以使用StageinitOwner属性将另一个Stage作为所有者,因此任务栏上不会出现其他图标

    您可以将initStyle属性与TRANSPARENTUNDECORATED{}一起使用,这将确保只有内容可见

    最后,您可以使用focusedProperty来检查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中打开它,而是在当前Stage中绘制一个ScrollPane,该ScrollPaneStage的内容重叠,例如使用AnchorPaneGroup作为根,但是第一种解决方案的优点是,您不必绑定到mainStage的维度(弹出窗口可以有您想要的任何大小)