JavaFX:删除行后更新GridPane的最佳方法?

时间:2014-10-16 09:19:25

标签: javafx row repaint gridpane

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

GridPane before row (user entry) deletion

GridPane after row (user entry) deletion

更新:下面的代码示例:

显而易见的问题是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来运行相应的命令。

1 个答案:

答案 0 :(得分:0)

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