I have to set a "quiz" in Java, using JPanel
and JRadioButton
.
My code starts with reading a text from a file and putting it on a panel, with radio buttons, button groups and panel. So far, so good.
However my problem starts when I have to collect the data from the user and compare it with the right answers.
I have class Questions, Answers and Read (besides main and display on panel).
My way of thinking was that when the user clicks the submit
button the code stars to check to quiz. However, nothing happens when I click it on the window opened.
I collect the data to ArrayList
for comparison.
The checkQuiz
method is supposed to be called after the user submits the quiz. It compares the radio button selected text with an answer. The program is supposed to be "running" until the user clicks the "submit" button, however I believe it does not happen.
I tried to use ActionListener
in the code but I couldn't compare the user's choice with the data I am using.
I am sorry for the lots of code. I tried to post a mcve question. As far as I know the code is compilable, but I couldn't neglect any more lines.
Thank you for your help, and the code is below.
Class DisplayOnPanel creates a Frame for the subclass to use:
import javax.swing.JFrame;
public class DisplayOnPanel extends JFrame {
JFrame frame = new JFrame();
public DisplayOnPanel(){
frame.setSize(500,500);
}
}
Class Main:
public class Main {
public static void main (String[]args){
new Read();
}
}
Clsas Questions:
public class Question {
private String _question;
private String _option1;
private String _option2;
private String _option3;
private String _option4;
private int _qIndex=0;
public Question(String question, String option1, String option2, String option3,
String option4){
this._question = question;
this._option1 = option1;
this._option2 = option2;
this._option3 = option3;
this._option4 = option4;
}
public void set_qIndex(int index) {
this._qIndex = index;
}
Class Read - Reads from a file and then displays the results on the panel. It also fills ArrayLists with Answers, Questions, ButtonGroups and JPanels.
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Read extends DisplayOnPanel {
protected ArrayList<Question> Questions = new ArrayList<>();
protected ArrayList<ButtonGroup> BG = new ArrayList<>();
protected ArrayList<JPanel> JP = new ArrayList<>();
protected ArrayList<Answer> Answers = new ArrayList<>();
protected int qNumber = 0, finalscore = 0;
private JLabel lblScore;
private JToggleButton Submit = new JToggleButton();
//constructor
public Read() {
super();
//a "label" in the file will indicate the final score
final int NUMBER_OF_LABELS_ADDED_TO_FRAME = 1;
int number_of_lines_in_the_file, final_score = 0;
try {
number_of_lines_in_the_file = read(Questions);
addButtonsToFrame(Questions, number_of_lines_in_the_file +
NUMBER_OF_LABELS_ADDED_TO_FRAME, BG, JP);
Submit.setText("Submit Quiz"); //create a submit button
JPanel SubmitPanel = new JPanel();
SubmitPanel.setVisible(true);
this.add(SubmitPanel);
SubmitPanel.add(Submit);
Submit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
for (int i = 0; i < BG.size(); i++) {
//handle cases of the user didn't complete the test
if (BG.get(i).getSelection()==null) {
JOptionPane.showMessageDialog(frame, "Exam not finished - Restart.");
i=BG.size()-1; //finish the loop
frame.setVisible(false);
dispose();
new Read();
}
}
checkQuiz(BG, Answers, ONE_QUESTION_GRADE); //check quiz
Submit.setEnabled(false); //can't redo quiz //
// unless "Restart" pressed
}
});
//adding final score label
lblScore = new JLabel("Your Final Score: " + finalscore);
add(lblScore);
pack();
this.setVisible(true);
while (!Submit.isSelected()) {
if (Submit.isSelected()) {
checkQuiz(BG, Answers);
}
}
} catch (FileNotFoundException e) {
System.out.println("couldn't open file");
}
}
//the method reads from the file
//returns the number of lines (quesiton) in the file
public int read(ArrayList<Question> Questions) throws FileNotFoundException {
int number_of_lines = 0;
try {
File f = new File("C:\\Users\\Assaf\\Desktop\\exam.txt");
Scanner input = new Scanner(f);
//read from file direcly into the constructor
while (input.hasNext()) {
Question q = new Question((input.nextLine())
, (input.nextLine()),
(input.nextLine()),
(input.nextLine()),
(input.nextLine()));
//adding the question and the answers to an array
Questions.add(q);
number_of_lines++;
q.set_qIndex(number_of_lines);
Answers.add(new Answer(q));
}
input.close();
} catch (FileNotFoundException nf) {
System.out.println("couldn't open file");
}
//return number of lines in the file
return number_of_lines;
}
public void addButtonsToFrame(ArrayList<Question> q, int number_of_lines,
ArrayList<ButtonGroup> BG, ArrayList<JPanel> JP) {
int j = 0;
for (int i = 0; i < q.size(); i++) {
qNumber = i;
BG.add(new ButtonGroup());
JP.add(new JPanel());
JP.get(i).setSize(499, 400);
//creating buttons
JRadioButton option1 = new JRadioButton(q.get(i).get_option1());
option1.setActionCommand(q.get(i).get_option1());
JRadioButton option2 = new JRadioButton(q.get(i).get_option2());
option2.setActionCommand(q.get(i).get_option2());
JRadioButton option3 = new JRadioButton(q.get(i).get_option3());
option3.setActionCommand(q.get(i).get_option3());
JRadioButton option4 = new JRadioButton(q.get(i).get_option4());
option4.setActionCommand(q.get(i).get_option4());
//adding to group buttons
BG.get(j).add(option1);
BG.get(j).add(option2);
BG.get(j).add(option3);
BG.get(j).add(option4);
//adding the buttons to the panel
JP.get(j).add(option1);
JP.get(j).add(option2);
JP.get(j).add(option3);
JP.get(j).add(option4);
//setting layout that matches our goal
this.setLayout(new GridLayout(number_of_lines + 1, 1));
//set title and border for each question
JP.get(i).setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "question number " + qNumber + ": " + q.get(i).get_question()));
//adding the panel to the frame
this.add(JP.get(j));
//BG.get(i).getSelection()
JP.get(j).setVisible(true);
j++;
}
}
public void checkQuiz(ArrayList<ButtonGroup> BG, ArrayList<Answer> A) {
ArrayList<String> Selections = new ArrayList<>();
int CORRECT_ANSWER = 0;
for (int i = 0; i < BG.size(); i++) {
if (BG.get(i).getSelection().getActionCommand()
.compareTo(A.get(i).get_answer()) == CORRECT_ANSWER) {
finalscore = finalscore + 10;
}
}
}
Class Answer
public class Answer {
private String _question;
private String _answer;
private int _qIndex=0;
public Answer (Question q){
this._answer = q.get_option1();
this._question=q.get_question();
this._qIndex=q.get_qIndex();
}
Edit - posted my working code.
i) You need to set action command before getting it,
JRadioButton option1 = new JRadioButton(q.get(i).get_option1());
option1.setActionCommand(q.get(i).get_option1());
JRadioButton option2 = new JRadioButton(q.get(i).get_option2());
option2.setActionCommand(q.get(i).get_option2());
JRadioButton option3 = new JRadioButton(q.get(i).get_option3());
option3.setActionCommand(q.get(i).get_option3());
JRadioButton option4 = new JRadioButton(q.get(i).get_option4());
option4.setActionCommand(q.get(i).get_option4());
ii) You haven't set the final score in your label in the end of checkQuiz
method,
lblScore.setText("Your Final Score: " + finalscore);
iii) It is not advisable to use a while
loop. Also checkQuiz
method will not be invoked most of the time with the current logic you use. Hence use an ActionListener
interface instead of a while
,
Submit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
checkQuiz(BG, Answers);
}
});