Хорошо, вот сложный вопрос, который сводит меня с ума уже пару дней...
У меня есть два этапа: этап администрирования пользователей (контроллер: UsersAdminController.java) со следующей иерархией элементов : и этапе добавления пользователя: (Контроллер: AddUserController.java)
В качестве дочернего элемента в панель прокрутки верхней панели привязки на этапе администрирования пользователей (см. иерархию элементов) я добавляю во время инициализации UsersAdminController панель GridPane, предназначенную для вывода списка пользователей системы, как описано здесь Когда я добавляю пользователя через экран добавления пользователя, я пытаюсь обновить GridPane на этапе администрирования пользователей путем получения ссылки на UsersAdminController и последующего вызова метода, обновляющего его содержимое. Однако GridPane НЕ МОЖЕТ БЫТЬ ОБНОВЛЕН. (Похоже, я не могу выполнить какое-либо действие, связанное с графическим интерфейсом, ни с панелью прокрутки, ни с панелью сетки, хотя мне удается получить ссылку на соответствующий контроллер.
Код: вот как (правильно) инициализируется панель сетки с помощью метода инициализации UsersAdminController:
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());
}
Вот displayNonSudoUsers, который заполняет GridPane.
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++;
}
}
А вот метод, который вызывается по действию КНОПКИ ДОБАВИТЬ ПОЛЬЗОВАТЕЛЯ стадии добавления пользователя
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 — на метод, который пытается обновить GridPane, ПОВТОРНО ВЫЗЫВАЯ displayNonSudoUsers(). Я также экспериментировал, пытаясь делать различные вещи на панели прокрутки / панели сетки на этапе администрирования пользователей (например, удаление метки и т. д.), но НАДА!
Спасибо.
РЕДАКТИРОВАТЬ: И именно так я получаю ссылку на контроллер администратора пользователя (что, вероятно, правильно, потому что, например, мне удается sysout некоторые из его идентификаторов элементов и т. д.) в методе инициализации AddUserController.java
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();
}
UserAdministrationController
вAddUserController
? - person James_D   schedule 20.10.2014Parent root = (Parent) fxmlLoader.load(loc.openStream());
, я получу исключение NullPointerException, когда попытаюсь получить доступ кuac
. - person pkaramol   schedule 20.10.2014@FXML
, не инициализируйте ее. А именно удалить строкуgridPaneNonSudoUsers = new GridPane();
- person Uluk Biy   schedule 20.10.2014