Не получается получить контроллер в 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 шт):

Автор решения: World 006

Если вы переходите нажимая на кнопку в другой сценарий, то как мне кажется этот способ будет лучше:

@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));
    }
→ Ссылка
Автор решения: Perfect Voyage

Вы не можете так сделать, потому что 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());
}
→ Ссылка
Автор решения: NkL322

Проблема была в том, что сначала нужно вызвать метод 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();
                }
            });
→ Ссылка