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.
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.
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?
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:
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?
2 Answers
Answers 1
You're probably doing something like this to load the fxml file:
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.
To work around this, you could execute the code in the 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:
FXMLLoader loader = new FXMLLoader(getClass().getResource("myFXML.fxml")); quizSceneController controller = new quizSceneController(); controller.setMain(this); loader.setController(controller); Parent p = loader.load();
Answers 2
Your controller needs to implement the Initializable
interface
import javafx.fxml.Initializable; public final class QuizSceneController implements Initializable { @Override public void initialize(URL location, ResourceBundle resources) { // do stuff } }
0 comments:
Post a Comment