初始化javafx场景而不使用按钮事件。

时间:2022-07-25 17:01:14

I have created a new scene called quiz_scene and the quiz_scene_controller in a javafx project. This scene simulates a question and answer quiz game. The object of the scenes are the question_label and the answer_text_field or the answer_buttons. In total the number of questions are 7 and after the system directs into the next scene.

我在javafx项目中创建了一个名为quiz_scene和quiz_scene_controller的新场景。这个场景模拟了一个问答游戏。场景的对象是question_label和answer_text_field或answer_buttons。总共有7个问题,系统进入下一个场景后。

I want when I am entering the system to perform a query in an initialize function to a sql database with the questions and answers to fetch the current questions and answers. This procedure needs to be occured once when the system open the quiz_scene (and also every time the answer button is pressed). I tried to add the functionality of the query inside the **@FXML public void initialize()**, however it did not work.

当我进入系统时,我希望在一个初始化函数中对sql数据库执行查询,其中包含问题和答案,以获取当前的问题和答案。当系统打开quiz_scene时(以及每次按下应答按钮时)需要执行此过程一次。我尝试在**@FXML公共void initialize()** *中添加查询的功能,但它不起作用。

When I tried to add the functionality in a button event the query worked and I am able to change the label and the buttons of the scene using the info from the db. One of the issues I found is the fact that when I am performing the query I am creating a reference to my main class which contains the loader for the quiz_scene. Without event I am not retrieving the current object and I am retrieving a null one. How I can do so without the use of a button? Why my object is null?

当我尝试在按钮事件中添加功能时,查询工作了,我可以使用db的信息更改场景的标签和按钮。我发现的一个问题是,当我执行查询时,我正在创建一个对我的主类的引用,它包含了quiz_scene的加载程序。没有事件,我没有检索当前对象,而是检索一个空对象。如果没有按钮,我怎么能做到呢?为什么我的对象是空的?

The code can be found here: 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);
 }
}

Finally the way I am loading the fxml from the main class is the following:

最后,我从主类加载fxml的方式如下:

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

EDIT: How can instead of using the button to initialize the whole scene using the code of chooseNextQuestion?

编辑:如何替代使用chooseNextQuestion的代码来初始化整个场景?

2 个解决方案

#1


6  

You're probably doing something like this to load the fxml file:

您可能正在做这样的事情来加载fxml文件:

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

However the initialize method is executed during FXMLLoader.load i.e. before setMain is called. The flow field still contains null at that time.

然而,在FXMLLoader中执行initialize方法。在调用setMain之前加载。当时流场仍然包含null。

To work around this, you could execute the code in the setter:

为了解决这个问题,您可以在setter中执行代码:

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

Alternatively remove the fx:controller attribute from the root element of the fxml and create/initialize the controller yourself before loading the fxml file:

或者从fxml的根元素中删除fx:controller属性,并在加载fxml文件之前创建/初始化控制器:

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

#2


1  

Your controller needs to implement the Initializable interface

控制器需要实现Initializable接口

import javafx.fxml.Initializable;

public final class QuizSceneController implements Initializable {

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

#1


6  

You're probably doing something like this to load the fxml file:

您可能正在做这样的事情来加载fxml文件:

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

However the initialize method is executed during FXMLLoader.load i.e. before setMain is called. The flow field still contains null at that time.

然而,在FXMLLoader中执行initialize方法。在调用setMain之前加载。当时流场仍然包含null。

To work around this, you could execute the code in the setter:

为了解决这个问题,您可以在setter中执行代码:

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

Alternatively remove the fx:controller attribute from the root element of the fxml and create/initialize the controller yourself before loading the fxml file:

或者从fxml的根元素中删除fx:controller属性,并在加载fxml文件之前创建/初始化控制器:

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

#2


1  

Your controller needs to implement the Initializable interface

控制器需要实现Initializable接口

import javafx.fxml.Initializable;

public final class QuizSceneController implements Initializable {

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