Не получается получить контроллер в JavaFX
Я хотел бы передавать в класс контроллера объект Vote, однако происходит ошибка:
Cannot invoke "sample.VoteController.setVote(sample.Vote)" because "voteController" is null
Что я делаю не так?
button.setOnAction(actionEvent -> {
try {
Stage stage = (Stage) ((Node) actionEvent.getSource()).getScene().getWindow();
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("assets/vote.fxml")));
VoteController voteController = loader.getController();
voteController.setVote(vote);
stage.setScene(new Scene(loader.load()));
} catch (IOException e) {
e.printStackTrace();
}
});
Ответы (3 шт):
Если вы переходите нажимая на кнопку в другой сценарий, то как мне кажется этот способ будет лучше:
@FXML
void back(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("Main.fxml")));
Stage window = (Stage) back.getScene().getWindow();
window.setScene(new Scene(root, 600, 400));
}
Вы не можете так сделать, потому что VoteController ещё не инициализирован. Но вы можете вызвать обратное действие, в контроллере № 2 используя паттерн синглтон.
Предположим, у нас есть контроллер А и Б.
Создадим вспомогательный класс, который будет возвращать нам контроллер А
public class SinglToneController {
private static A controllerRol;
public SinglToneController(A controllerRol) {
SinglToneController.controllerRol = controllerRol;
}
@NotNull
public static A getControllerRol() {
return controllerRol;
}
}
В обоих случаях, нам понадобится метод initialize где :
Для контроллера А - мы отдадим ссылку на контроллер А классу SinglToneController
// A
public void initialize(){
new SinglToneController(this);
}
public Pane getVote() {
// Pane для примера
return vote;
}
Для контроллера Б, для сетера setVote, мы запросим элемент (так же в блоке initialize) у ссылки на синглтон А.
P.S в контроллере A должен быть геттер vote
//B
public void initialize(){
setVote(SinglToneController.getControllerRol().getVote());
}
Проблема была в том, что сначала нужно вызвать метод load, а затем уже можно проводить манипуляции с контроллером. Также, с такой логикой нельзя будет обратиться к данным из initialize(), так как он сработает до метода setvote().
button.setOnAction(actionEvent -> {
try {
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("assets/vote.fxml")));
Parent parent = loader.load();
VoteController voteController = loader.getController();
voteController.setVote(vote);
voteController.createPieChart();
Stage stage = (Stage) ((Node) actionEvent.getSource()).getScene().getWindow();
Scene scene = new Scene(parent);
stage.setScene(scene);
} catch (IOException | SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
});