Подтвердить что ты не робот

Инициализировать сцену javafx без использования события кнопки

Я создал новую сцену под названием quiz_scene и quiz_scene_controller в проекте javafx. Эта сцена имитирует вопрос и ответ на викторину. Объектом сцен являются question_label и answer_text_field или answer_buttons. В целом количество вопросов равно 7 и после того, как система направляется в следующую сцену.

Я хочу, когда я вхожу в систему для выполнения запроса в функции инициализации в базу данных sql с вопросами и ответами для получения текущих вопросов и ответов. Эта процедура должна выполняться один раз, когда система открывает quiz_scene (а также каждый раз, когда нажимается кнопка ответа). Я попытался добавить функциональность запроса внутри **@FXML public void initialize()**, однако это не сработало.

Когда я попытался добавить функциональность в событие кнопки, запрос работал, и я могу изменить метку и кнопки сцены, используя информацию из db. Одна из проблем, которые я обнаружил, это тот факт, что когда я выполняю запрос, я создаю ссылку на мой основной класс, содержащий загрузчик для quiz_scene. Без события я не извлекаю текущий объект, и я получаю нулевой. Как я могу сделать это без использования кнопки? Почему мой объект равен нулю?

Код можно найти здесь: code.

public class quizSceneController{

 private Flow flow;
 public void setMain(Flow flow){ this.flow = flow;}
 @FXML Button answerbutton;
 @FXML Text timeField, scoreField;
 @FXML public Label question, showQuestionCounter, answer, questionId, questionType, questionSpeed;
 NextQuestion nextQuestion;
 public String temp, temp2;
 public GridPane takingTestPane = new GridPane();

 public void chooseNextQuestion(Flow flow){

    try {
        this.flow.nextQ = false;
        this.flow.startTime = System.currentTimeMillis();
        //Choosing the next question
        String sql = "select * from Questions where Subject = ? and Level = ?  and questionId = ?";
        PreparedStatement pst = 
this.flow.connectionQuestions.prepareStatement(sql);
        pst.setString(1, this.flow.textSubjectQTest);
        pst.setString(2, this.flow.user_course_level);
        pst.setString(3, this.flow.list.get(counter));
        ResultSet rs = pst.executeQuery();
        if (rs.next()) {

            temp = rs.getString("Question");
            temp2 = rs.getString("Answer");

            pst.execute();
            pst.close();
        } else {
            System.out.println("No data for this subject");
        }

    } catch (Exception a) {
        System.out.println(a);
    }
 }

 @FXML private void myButton(ActionEvent event){

    chooseNextQuestion(this.flow);
    this.question.setText(temp);
 }
 @FXML public void initialize(){

    chooseNextQuestion(this.flow);
    this.question.setText(temp);
 }
}

Наконец, способ загрузки fxml из основного класса следующий:

loader = new FXMLLoader();         
loader.setLocation(Flow.class.getResource("/gui/quiz/quiz.fxml"));
quizPane = loader.load();
quizSceneController quiz = loader.getController();

РЕДАКТИРОВАТЬ: Как можно вместо кнопки инициализировать всю сцену, используя код selectNextQuestion?

4b9b3361

Ответ 1

Вероятно, вы делаете что-то вроде этого, чтобы загрузить файл fxml:

FXMLLoader loader = new FXMLLoader(getClass().getResource("myFXML.fxml"));
Parent p = loader.load();
quizSceneController controller = loader.getController();
controller.setMain(this);

Однако метод initialize выполняется во время FXMLLoader.load, то есть до вызова setMain. Поле flow все еще содержит null в это время.

Чтобы обойти это, вы можете выполнить код в установщике:

public void setMain(Flow flow){
    this.flow = flow;
    chooseNextQuestion(this.flow);
    this.question.setText(temp);
}

Альтернативно удалите атрибут fx:controller из корневого элемента fxml и создайте/инициализируйте контроллер самостоятельно перед загрузкой файла fxml:

FXMLLoader loader = new FXMLLoader(getClass().getResource("myFXML.fxml"));
quizSceneController controller = new quizSceneController();
controller.setMain(this);
loader.setController(controller);
Parent p = loader.load();

Ответ 2

Контроллер должен реализовать Initializable интерфейс

import javafx.fxml.Initializable;

public final class QuizSceneController implements Initializable {

     @Override
     public void initialize(URL location, ResourceBundle resources) {
           // do stuff
     }
}