0

i'm trying to make a multiple choice quiz game, at the moment the SQLite data base is set up (i think) and the data for the questions are stored. However, when i try to display the question onto the screen the question does not show. i have no idea what the problem is.

Error

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.ninjanumbers, PID: 1603 java.lang.NullPointerException: Attempt to invoke virtual method 'int com.ninjanumbers.Question.getAnswerNum()' on a null object reference at com.ninjanumbers.NumGame.checkAnswer(NumGame.java:129) at com.ninjanumbers.NumGame.access$400(NumGame.java:19) at com.ninjanumbers.NumGame$1.onClick(NumGame.java:78) at android.view.View.performClick(View.java:7448) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) at android.view.View.performClickInternal(View.java:7425) at android.view.View.access$3600(View.java:810) at android.view.View$PerformClick.run(View.java:28305) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

NumGame.java

public class NumGame extends AppCompatActivity {
// defining variables
private TextView textViewQuestion;
private TextView textViewScore;
private TextView textViewQuestionCount;
private TextView textViewCountDown;
private RadioGroup rbGroup;
private RadioButton rb1;
private RadioButton rb2;
private RadioButton rb3;
private Button btnConfirm;

private ColorStateList textColorDefaultRb; // default text colour for radio button

private List<Question> questionsList;
private int questionCounter;
private int questionCountTotal;
private Question currentQuestion;

private int score;
private boolean answered;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_num_game);

    // initializing variables
    textViewQuestion = findViewById(R.id.txtQuestionDisplay);
    textViewScore = findViewById(R.id.txtScore);
    textViewQuestionCount = findViewById(R.id.txtQuestionTrack);
    textViewCountDown = findViewById(R.id.txtTime);
    rbGroup = findViewById(R.id.radioGroup);
    rb1 = findViewById(R.id.radioButton1);
    rb2 = findViewById(R.id.radioButton2);
    rb3 = findViewById(R.id.radioButton3);
    btnConfirm = findViewById(R.id.btnConfirm);

    textColorDefaultRb = rb1.getTextColors(); // gets colour of the radio button

    // creates a new instance of the data retriever for the data base data
    QuizDbHelper dbHelper = new QuizDbHelper(this);
    // this line also creates the data base when called for the first time
    questionsList = dbHelper.getAllQuestions();

    questionCountTotal = questionsList.size();
    Collections.shuffle(questionsList); // randomises question order

    //textViewQuestion.setText("hello"); // ToDo: fix the display text bug


    showNextQuestion();

    btnConfirm.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!answered){
                // handles an answered question (checked radio button)
                if (rb1.isChecked() || rb2.isChecked() || rb3.isChecked()){
                    checkAnswer();
                    // handles an unanswered question
                } else {
                    Toast.makeText(NumGame.this, "Please select an answer.", Toast.LENGTH_SHORT).show();
                }
            } else {
                showNextQuestion();
            }
        }
    });

}

// logic for displaying question
private void showNextQuestion() {
    // resets the colour of the radio buttons
    rb1.setTextColor(textColorDefaultRb);
    rb2.setTextColor(textColorDefaultRb);
    rb3.setTextColor(textColorDefaultRb);
    // unselects buttons
    rbGroup.clearCheck();



    // starts at 0 and increments each time a question is used from the list
    if (questionCounter < questionCountTotal) {
        currentQuestion = questionsList.get(questionCounter);
        // updates the screen and displays the next question and options
        textViewQuestion.setText(currentQuestion.getQuestion());
        rb1.setText(currentQuestion.getOption1());
        rb2.setText(currentQuestion.getOption2());
        rb3.setText(currentQuestion.getOption3());

        // increments the question count
        questionCounter ++;

        textViewQuestionCount.setText("Question: " + questionCounter + "/" + questionCountTotal);
        answered = false;
        btnConfirm.setText("Confirm");
    } else {
    //finishQuiz();
        textViewQuestion.setText("hello");
    }
}

// checks if a answer is correct or not
private void checkAnswer() {
    answered = true;
    RadioButton rbSelected = findViewById(rbGroup.getCheckedRadioButtonId());
    int answerNum = rbGroup.indexOfChild(rbSelected) + 1;

    if (answerNum == currentQuestion.getAnswerNum()) {
        score++;
        textViewScore.setText("Score: " + score);
    }

    showSolution();
}

private void showSolution() {
    // sets radio buttons to red
    rb1.setTextColor(Color.RED);
    rb2.setTextColor(Color.RED);
    rb3.setTextColor(Color.RED);

    // displaying the correct answer
    switch (currentQuestion.getAnswerNum()){
        case 1:
            rb1.setTextColor(Color.GREEN);
            textViewQuestion.setText("Answer 1 is correct!");
            break;
        case 2:
            rb2.setTextColor(Color.GREEN);
            textViewQuestion.setText("Answer 2 is correct!");
            break;
        case 3:
            rb3.setTextColor(Color.GREEN);
            textViewQuestion.setText("Answer 3 is correct!");
            break;
    }

    if (questionCounter < questionCountTotal){
        btnConfirm.setText("Next");
    } else {
        btnConfirm.setText("Finish");
    }

}

QuizDbHelper.java

public class QuizDbHelper extends SQLiteOpenHelper{
// defines constants
private static final String DATABASE_NAME = "NumberNinjas.db";
private static final int DATABASE_VERSION = 1;

// holds reference to the data base
private SQLiteDatabase db;

public QuizDbHelper(Context context) {
    super(context,DATABASE_NAME, null, DATABASE_VERSION);
}
// creates the table
@Override
public void onCreate(SQLiteDatabase db) {
    this.db = db;
    // SQL commands to create table
    final String SQL_CREATE_QUESTIONS_TABLE = "CREATE TABLE " +
            QuestionTable.TABLE_NAME + " ( " +
            QuestionTable._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + // bug was here, game crashed because the sql creary was wrong and when the "_id" value was added the "Integer" query was concatenated with it
            QuestionTable.COLUMN_QUESTION + " TEXT, " +
            QuestionTable.COLUMN_OPTION1 + " TEXT, " +
            QuestionTable.COLUMN_OPTION2 + " TEXT, " +
            QuestionTable.COLUMN_OPTION3 + " TEXT, " +
            QuestionTable.COLUMN_ANSWER_NUM + " INTEGER" +
            ")";

    db.execSQL(SQL_CREATE_QUESTIONS_TABLE);

    // calls the function that fills the table with data
    fillQuestionsTable();
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // deletes database and creates it again if the table already exists
    db.execSQL("DROP TABLE IF EXISTS " + QuestionTable.TABLE_NAME);
    onCreate(db);
}
// fills the table with data

/***
 * This is where the questions are added.
 *
 * future improvements can be to make these questions randomly generated
 * instead of hard coded questions
 */
private void fillQuestionsTable() {
    Question q1 = new Question("A is Correct", "A", "B", "C",1);
    // calls add questions function and adds a question
    addQuestion(q1);

    Question q2 = new Question("B is Correct", "A", "B", "C",2);
    // calls add questions function and adds a question
    addQuestion(q2);

    Question q3 = new Question("C is Correct", "A", "B", "C",3);
    // calls add questions function and adds a question
    addQuestion(q3);

    Question q4 = new Question("A is Correct again", "A", "B", "C",1);
    // calls add questions function and adds a question
    addQuestion(q4);

    Question q5 = new Question("B is Correct again", "A", "B", "C",2);
    // calls add questions function and adds a question
    addQuestion(q5);
}
private void addQuestion(Question question) {
    // creates an new instance of the content value class and sets its identifier to cv
    ContentValues cv = new ContentValues();
    // retrieves the data and implements it to the data base
    cv.put(QuestionTable.COLUMN_QUESTION, question.getQuestion());
    cv.put(QuestionTable.COLUMN_OPTION1, question.getOption1());
    cv.put(QuestionTable.COLUMN_OPTION2, question.getOption2());
    cv.put(QuestionTable.COLUMN_OPTION3, question.getOption3());
    cv.put(QuestionTable.COLUMN_ANSWER_NUM, question.getAnswerNum());
    db.insert(QuestionTable.TABLE_NAME, null, cv);
}
// retrieves the data of the database
public List<Question> getAllQuestions() {
    List<Question> questionList = new ArrayList<>();
    db = getReadableDatabase();
    // creates a entry point for the system to retrieve data
    Cursor c = db.rawQuery("SELECT * FROM " + QuestionTable.TABLE_NAME, null);

    // reading the table and allocating data to question class objects
    if (c.moveToFirst()) {
        do {
            Question question = new Question();
            question.setQuestion(c.getString(c.getColumnIndex(QuestionTable.COLUMN_QUESTION)));
            question.setOption1(c.getString(c.getColumnIndex(QuestionTable.COLUMN_OPTION1)));
            question.setOption2(c.getString(c.getColumnIndex(QuestionTable.COLUMN_OPTION2)));
            question.setOption3(c.getString(c.getColumnIndex(QuestionTable.COLUMN_OPTION3)));
            question.setAnswerNum(c.getInt(c.getColumnIndex(QuestionTable.COLUMN_ANSWER_NUM)));
            // creates question object for each entry in the database and adds them to the question list
            questionList.add(question);
        } while (c.moveToNext());


    }
    c.close();
    return questionList;
}

sorry for the large amount of code i just have no idea what is wrong with it.

zzixM
  • 1
  • 1
    You are in `checkAnswer` and you are calling `currentQuestion.getAnswerNum()` when `currentQuestion` is `null`. – Stephen C Jun 23 '21 at 11:21
  • why is current question null though? – zzixM Jun 24 '21 at 08:55
  • Not sure. You may need to use a debugger to figure that out. For example, check that `currentQuestion = questionsList.get(questionCounter);` is called, and find what it assigns. – Stephen C Jun 24 '21 at 10:47

0 Answers0