好吧,这是一个棘手的问题,这几天来一直让我抓狂...
作为users admin阶段(参见elements hierarchy)上方锚定窗格的滚动窗格的子窗格,我在UsersAdminController初始化期间添加了一个GridPane,该GridPane用于列出系统的用户(如本文所述)。当我通过user addition屏幕添加用户时,我尝试通过获取对UsersAdminController的引用,然后调用更新其内容的方法来更新users AdminController的GridPane。但是,无法更新GridPane。(我似乎无法对滚动窗格和gridpane执行任何与GUI相关的操作,尽管我设法获得了对相关控制器的引用。
代码:下面是如何通过UserSadminController的initialize方法(正确)初始化gridpane的:
public void initialize(URL location, ResourceBundle resources) {
gridPaneNonSudoUsers = new GridPane();
gridPaneNonSudoUsers.setId("gridPaneNonSudoUsers");
// setting column widths for the grid pane
gridPaneNonSudoUsers.getColumnConstraints().add(new ColumnConstraints(145));
gridPaneNonSudoUsers.getColumnConstraints().add(new ColumnConstraints(85));
gridPaneNonSudoUsers.getColumnConstraints().add(new ColumnConstraints(210));
gridPaneNonSudoUsers.getColumnConstraints().add(new ColumnConstraints(150));
srcPaneUsers.setContent(gridPaneNonSudoUsers);
gridPaneNonSudoUsers.setAlignment(Pos.CENTER);
displayNonSudoUsers(getSystemNonSudoUsers());
}
下面是填充GridPane的displayNonSudoUsers
public void displayNonSudoUsers(ArrayList nonSudoUsers){
// adding some space between lines
gridPaneNonSudoUsers.setVgap(15);
Label lblHeaderUsername = new Label("Username");
lblHeaderUsername.setPadding(new Insets(0, 0, 0, 20));
lblHeaderUsername.setId("lblHeaderUsername");
Label lblHeaderIsProtected = new Label("Προστασία");
lblHeaderIsProtected.setId("lblHeaderIsProtected");
GridPane.setHalignment(lblHeaderUsername, HPos.LEFT);
GridPane.setHalignment(lblHeaderIsProtected, HPos.CENTER);
// adding header elements to GridPane
GridPane.setColumnIndex(lblHeaderUsername, 0);
GridPane.setRowIndex(lblHeaderUsername, 0);
GridPane.setColumnIndex(lblHeaderIsProtected, 1);
GridPane.setRowIndex(lblHeaderIsProtected, 0);
gridPaneNonSudoUsers.getChildren().addAll(lblHeaderUsername,
lblHeaderIsProtected);
// adding users
int i = 1; // starting from 2nd row given that 1st row belongs to
// headers
for (NonSudoUser nsuser : nonSudoUsers) {
/**** Label ****/
String username = nsuser.getUsername();
Label lblUsername = new Label(username);
lblUsername.setPadding(new Insets(5, 0, 5, 20));
lblUsername.setId("lbl" + username);
GridPane.setHalignment(lblUsername, HPos.LEFT);
/**** Image ****/
boolean isProtected = nsuser.isProtected();
ImageView imgIsProtected = new ImageView(
isProtected ? "/resources/media/notOK.png"
: "/resources/media/ok.png");
imgIsProtected.setFitHeight(20);
imgIsProtected.setFitWidth(20);
imgIsProtected.setId("img" + username);
GridPane.setHalignment(imgIsProtected, HPos.CENTER);
/**** Button for protection ****/
Button btnSetProtected = new Button("Ενεργοποίηση Προστασίας");
btnSetProtected.setId("btnProt" + username);
btnSetProtected.setDisable(!isProtected);
GridPane.setHalignment(btnSetProtected, HPos.CENTER);
/**** Button for deletion ****/
Button btnDeleteUser = new Button("Διαγραφή Χρήστη");
btnDeleteUser.setId("btnDel" + username);
GridPane.setHalignment(btnDeleteUser, HPos.CENTER);
// delete user in a seperate thread
btnDeleteUser.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
Action response = Dialogs
.create()
.owner(root)
.title("ΔΙΑΓΡΑΦΗ ΧΡΗΣΤΗ")
.masthead(
"ΠΡΟΣΟΧΗ! ΠΡΟΚΕΙΤΑΙ ΝΑ ΔΙΑΓΡΑΨΕΤΕ ΤΟ ΧΡΗΣΤΗ: "
+ username)
.message("ΕΙΣΑΣΤΕ ΣΙΓΟΥΡΟΙ?")
.actions(Dialog.ACTION_OK, Dialog.ACTION_CANCEL)
.showConfirm();
if (response == Dialog.ACTION_CANCEL)
return;
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))
toErase.add(nodeToErase);
}
gridPaneNonSudoUsers.getChildren()
.removeAll(toErase);
// rearrangeGridPane(); - TBD
return null;
}
});
}
});
executorUserDeletion.submit(task);
}
});
// adding user-related gui items
GridPane.setColumnIndex(lblUsername, 0);
GridPane.setRowIndex(lblUsername, i);
GridPane.setColumnIndex(imgIsProtected, 1);
GridPane.setRowIndex(imgIsProtected, i);
GridPane.setColumnIndex(btnSetProtected, 2);
GridPane.setRowIndex(btnSetProtected, i);
GridPane.setColumnIndex(btnDeleteUser, 3);
GridPane.setRowIndex(btnDeleteUser, i);
gridPaneNonSudoUsers.getChildren().addAll(lblUsername,
imgIsProtected, btnSetProtected, btnDeleteUser);
i++;
}
}
下面是在用户添加阶段的ADD USER按钮操作时调用的方法
public void createUser() throws UserCreationException {
String username, password1, password2;
username = txtUsername.getText();
password1 = txtPassword1.getText();
password2 = txtPassword2.getText();
LinuxCommand lc = new LinuxCommand(System.getProperty("user.dir")+"/adduser.sh", username, password2);
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws Exception {
lc.execute();
return null;
}
};
task.setOnFailed(new EventHandler<WorkerStateEvent>() {
public void handle(WorkerStateEvent t) {
System.out.println("FAILURE creating " + username);
System.out.println("exit code: " + lc.getExitCode());
}
});
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
if (lc.getExitCode() != 0)
// show dialog
return;
System.out.println("Successfully created new user: " + username + " With exit code: " + lc.getExitCode());
Platform.runLater(new Task<Void>() {
@Override
public Void call() throws Exception {
uac.addUser();
return null;
}
});
}
});
executorUserCreation.submit(task);
其中,uac是对UserAdministrationController.java和adduser的引用,该方法试图通过再次调用displayNonSudoUsers()更新GridPane。我还尝试在用户管理阶段的滚动窗格/网格窗格上做各种事情(例如,删除标签等),但不是!
多谢了。
public void initialize(URL location, ResourceBundle resources) {
// need to access UsersAdminController to update users list
// when adding user
URL loc = getClass().getResource("/resources/fxml/UsersAdminPane.fxml"); // the UsersAdmin fxml
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(loc);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try {
Parent root = (Parent) fxmlLoader.load(loc.openStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
uac = (UsersAdminController)fxmlLoader.getController();
}
在此代码中:
public void initialize(URL location, ResourceBundle resources) {
// need to access UsersAdminController to update users list
// when adding user
URL loc = getClass().getResource("/resources/fxml/UsersAdminPane.fxml"); // the UsersAdmin fxml
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(loc);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
try {
Parent root = (Parent) fxmlLoader.load(loc.openStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
uac = (UsersAdminController)fxmlLoader.getController();
}
加载usersadminpane.fxml
的新副本,获取对其控制器的引用...然后丢弃视图(root
),永远不要对它执行任何操作。由于该视图从未显示,因此在控制器上调用方法永远不会产生您将看到的任何更新。
您需要获得对与现有视图关联的控制器的引用,并对其调用方法,而不是创建一个新的控制器。假设您从UserSadminController
加载AddUser fxml文件,您可以从FXMLLoader
获取AddUserController
并通过在AddUserController
中定义一个setUserSadminController(...)
方法传递对UserSadminController
的引用。
在JavaFX中,我使用ListView显示添加到集合或从集合中移除的项目。我已经创建了一个observableSet,用于与ListView一起显示更新,但当集合更改时,ListView没有正确更新。这是我的代码和解决方法。但为什么它没有按预期工作? 问题:每次更新可观察集时,我必须继续设置ListView,如上图和下图所示。否则更改不会显示在ListView中。
我是JavaFX的新手。我试图编程一个简单的图形用户界面,但我面临着那些可能相关的问题。我用文件选择器设置文件,并想做相当基本的操作: 保存最后使用的文件夹 在VBox中写入选中文件的名称 这是我的代码(编译): 我无法刷新节点以设置当前初始目录或在VBox上显示collecName。我试图通过重新加载对象或调整窗口大小来重新生成它们,但没有任何效果。当我在控制台上打印变量时,我看到它们发生了变化
我有1个“viewelements”-类,1个控制器和1个fxml-文件。 ViewElements-Class包含FXML的元素,如按钮和文本字段。Controller-Class包含业务逻辑。 我试图更新文本字段“TextFieldDateIausWaeHlen”,我想将文件的路径设置到文本字段中,但我的方法不起作用。 我的错误在哪里?
我试图理解如何在多线程环境中更新ProgressBar。我在这里做错了什么,但我不知道是什么。这只需每隔3秒填满一次,但不会: 我错过了什么?
我刚刚创建了一个TablView,我成功地将数据放入其中。问题是当我双击一个单元格(要更新)时,它会显示更新的数据,但当我单击离开时,更新的单元格会显示旧数据! 这里的代码: 有人能帮帮我吗?厚度
问题内容: 我在Mac上使用Flask(python软件包)时,第一次写css时显示正常。但是,当我更新它并尝试检查它时,我只看到第一个CSS样式。我尝试重新启动终端,以及重新安装Flask。有什么建议?谢谢。以下是HTML: 这是CSS: 问题答案: 如前所述,问题与浏览器缓存有关。 为了解决这个问题,你可以向静态(css,js)链接中添加一些动态变量。我更喜欢每个文件的上次修改时间戳。 这是一