我正在使用 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 以运行相应的命令。