【问题标题】:JavaFX: Best way to update GridPane after row deletion?JavaFX:删除行后更新 GridPane 的最佳方法?
【发布时间】:2014-12-11 14:22:03
【问题描述】:

我使用 GridPane(在 ScrollPane 内)作为包含用户条目的表格。 每行包含一个用户名(标签)、一个描述其状态的图标(ImageView)和两个按钮,第二个按钮用于删除用户条目。 下面的两张图片描绘了用户条目删除前后的滚动窗格

更新:代码示例如下:

明显的问题是 GridPane 项目不会自动重新排列,删除的行仍然占用空间。 我是否必须提供一种手动重新排列的方法,还是有更简单的方法?

for (NonSudoUser nsuser : nonSudoUsers) { // the users I want to show in the gridpane
    // user row
    RowConstraints row = new RowConstraints(30);
    gridPaneNonSudoUsers.getRowConstraints().add(row);

    // code that adds username label, status icon, checkstatus button - irrelevant I think to our issue
    // adding delete user button now:
    Button btnDeleteUser = new Button("Delete User");
    btnDeleteUser.setId("btnDel"+username); // explained below
    // delete user in a seperate thread
    btnDeleteUser.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
        // confirmation dialog here - omitted for brevity               
            Task<Void> task = new Task<Void>() {
            @Override
                public Void call() throws Exception {
                    String username = ((Button) event.getSource()).getId();
                    LinuxCommand lc = new LinuxCommand("userdel", "-r", username);
                    lc.execute();
                    return null;
                    }
                };
                task.setOnFailed(new EventHandler<WorkerStateEvent>() {
                    public void handle(WorkerStateEvent t) {
                        System.out.println("FAILURE deleting  " + username);
                    }
                });
                task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
                    public void handle(WorkerStateEvent t) {
                        Platform.runLater(new Task<Void>() {
                            @Override
                            public Void call() throws Exception {
                                ArrayList<Node> toErase = new ArrayList<Node>();
                                for (Node nodeToErase: gridPaneNonSudoUsers.getChildren()) {
                                    if (nodeToErase.getId().endsWith(username)) // explaind below
                                        toErase.add(nodeToErase);
                                }
                                gridPaneNonSudoUsers.getChildren().removeAll(toErase);                                  
                                return null;
                            }
                        });
                    }
                });
                executorUserDeletion.submit(task);

检查天气元素 id 包含用户名的行是为了知道要删除哪些元素(在添加元素时,我会附加实际的用户名。因此,包含例如 testuser0 条目的 GridPane 行由具有以下 id 的元素组成: lbltestuser0,imgtestuser0,btnCheckStatustestuser0,btnDeleteUsertestuser0。 (只是启发式知道每次要删除哪一行) LinuxCommand 是一个自定义类,它在其构造函数中接受 vararg String 来运行相应的命令。

【问题讨论】:

  • 你能显示一些代码吗?
  • 我认为问题可能只是你有一个固定高度的行约束仍然存在。删除行时尝试删除行约束。不过,您实际上可能需要检查并减少所有后续行的行索引。 (这感觉就像是在呼唤TableView 而不是GridPane...)另一种选择可能是一起摆脱行约束,并使用CSS为节点添加一些额外的垂直填充网格窗格。
  • 非常感谢,这正是问题所在。我在没有任何RoWConstraints 的情况下尝试了它,并且更新完成了。我考虑了显式删除RowConstraints 的解决方案,但由于没有.setId() 方法,我无法弄清楚如何获取对每个RowConstraints 对象的引用
  • 我建议你在 VBox 中使用 HBoxes。将来您可能希望添加悬停或奇偶行样式等样式。这些任务可以通过 HBoxes-in-VBox 快速实现。
  • 另一个建议是使用 ListView 已经在之前的评论中提到的基本功能..

标签: javafx row repaint gridpane


【解决方案1】:

您可以将 setVisible(false) 和 setManaged(false) 一起应用于调用删除操作的行元素,但它会导致网格线相互重叠并导致网格线越来越暗行被删除。但除非您将其用作 GUI 功能,否则不会产生任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多