So I have this following code to make a quiz program. The code i'm using extends JDialog. I was wondering if there's a way to convert it to JPanel since when i try to run the code the window is all small and i can't seem to move the finished button next to the "Next" button. Also If i want to make the question be random how would one do that?
Thank You
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.util.Random;
import javax.swing.JRadioButton;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MultipleChoice extends JDialog {
int correctAns;
List<Question> questions = new ArrayList<Question>();
//asnwers
JRadioButton[] responses;
ButtonGroup group = new ButtonGroup();
//bottom
JButton next = new JButton("Next");
JButton finish = new JButton("Finish");
public MultipleChoice(){
super();
setModal(true);
setLayout( new BoxLayout(getContentPane(),BoxLayout.Y_AXIS)); //setting up boxlayout
questions.add(new Question("Which of the following is NOT one of the 5 great lakes?",new String[]{"Lake Mead","Lake Huron","Lake Michigan","Lake Erie"}, "Lake Mead"));
questions.add(new Question("What is the Capital of Colorado?",new String[]{"Boulder","Aspen","Denver","Cheyenne"},"Denver"));
questions.add(new Question("Each side of a baseball diamond is 90 feet in length. How far is it around the Baseball Diamond?",new String[]{"270","360","180","390"},"360"));
questions.add(new Question("What color do you get when you combine an equal amount of red paint with an equal amount of yellow paint?",new String[]{"Blue","Orange","Green","Pink"},"Orange"));
questions.add(new Question("How many sides does a trapezoid have?",new String[]{"3","4","5","6"},"2"));
questions.add(new Question("Which is a simile?",new String[]{"My sister is cute like a bunny","My mom has a manly snore","My dad is better than yours"},"My sister is cute like a bunny"));
questions.add(new Question("Polar bears eat penquins?",new String[]{"True","False"},"True"));
//bottom
next.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
setVisible(false);
}
});
finish.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
setVisible(false);
}
});
}
public int beginQuiz(){
int score=0;
for (Question q : questions){
displayQuestion(q);
if (group.getSelection().getActionCommand().equals(q.getans())){
score++;
}
}
dispose();
return score;
}
private void displayQuestion(Question q){
getContentPane().removeAll();
for (Enumeration buttonGroup=group.getElements(); buttonGroup.hasMoreElements(); ){
group.remove((AbstractButton)buttonGroup.nextElement());
}
JLabel questionText = new JLabel(q.getquestion());
getContentPane().add(questionText);
for (String answer : q.getanswers()){
JRadioButton radio = new JRadioButton(answer);
radio.setActionCommand(answer);
group.add(radio);
getContentPane().add(radio);
}
getContentPane().add(next);
getContentPane().add(finish);
pack();
setVisible(true);
}
public static void showSummary(int score){
JOptionPane.showMessageDialog(null,"All Done :), here are your results"+
"\nNumber of incorrect Answers: \t"+(7-score)+
"\nNumber of Correct Answers: \t"+(score)+
"\nPercent Correct: \t\t"+(int)(((float)(score)/7)*100)+"%"
);
if (((int)(((float)(score)/7)*100))> 0.6)
JOptionPane.showMessageDialog(null,"You Passed!");
else {
JOptionPane.showMessageDialog(null,"You are NOT Smarter than a 5th Grader");
}
}
public static void main(String[] args){
MultipleChoice quiz = new MultipleChoice();
int score = quiz.beginQuiz();
showSummary(score);
}
}
class Question {
private String question;
private String[] answers;
private String ans;
String getquestion(){ //getter
return question;
}
void setquestion(String str){ //setter
question = str;
}
String[] getanswers(){ //getter
return answers;
}
void setanswers(String[] str2){ //setter
answers = str2;
}
String getans(){ //getter
return ans;
}
void setans(String str3){ //setter
ans = str3;
}
public Question(String possibleQuestion ,String[] possibleAnswer , String correctAnswer){ //constructor
question = possibleQuestion;
answers = possibleAnswer;
ans = correctAnswer;
}
}
Updated with new edits
After i edited and tried to convert it into JPanel and using cardlayout like suggested I ran into a few error and can't seem to figure out how to get the String[] possibleanswer and string correctanswer to display for the system to know and match the correct answer. here are my updated code
Thank You
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.util.Random;
import java.awt.CardLayout;
import javax.swing.JRadioButton;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MultipleChoice {
int correctAns;
List<Question> questions = new ArrayList<Question>();
JPanel p=new JPanel();
CardLayout cards=new CardLayout();
int numQs;
int wrongs=0;
int total=0;
public static void main(String[] args){
new MultipleChoice();
}
public MultipleChoice(){
JFrame frame = new JFrame("Are you Smarter than a 5th Grader?");
frame.setResizable(true);
frame.setSize(500,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
questions.add(new Question("Which of the following is NOT one of the 5 great lakes?",new String[]{"Lake Mead","Lake Huron","Lake Michigan","Lake Erie"}, "Lake Mead"));
questions.add(new Question("What is the Capital of Colorado?",new String[]{"Boulder","Aspen","Denver","Cheyenne"},"Denver"));
questions.add(new Question("Each side of a baseball diamond is 90 feet in length. How far is it around the Baseball Diamond?",new String[]{"270","360","180","390"},"360"));
questions.add(new Question("What color do you get when you combine an equal amount of red paint with an equal amount of yellow paint?",new String[]{"Blue","Orange","Green","Pink"},"Orange"));
questions.add(new Question("How many sides does a trapezoid have?",new String[]{"3","4","5","6"},"2"));
questions.add(new Question("Which is a simile?",new String[]{"My sister is cute like a bunny","My mom has a manly snore","My dad is better than yours"},"My sister is cute like a bunny"));
questions.add(new Question("Polar bears eat penquins?",new String[]{"True","False"},"True"));
p.setLayout(cards);
numQs=questions.size();
for(int i=0;i<numQs;i++){
p.add(questions[i],"q"+i);
}
Random r=new Random();
int i=r.nextInt(numQs);
cards.show(p,"q"+i);
frame.add(p);
frame.setVisible(true);
}
public void next(){
if((total-wrongs)==numQs){
showSummary();
}else{
Random r=new Random();
boolean found=false;
int i=0;
while(!found){
i=r.nextInt(numQs);
if(!questions[i].used){
found=true;
}
}
cards.show(p,"q"+i);
}
}
public void showSummary(){
JOptionPane.showMessageDialog(null,"All Done :), here are your results"+
"\nNumber of incorrect Answers: \t"+wrongs+
"\nNumber of Correct Answers: \t"+(total-wrongs)+
"\nPercent Correct: \t\t"+(int)(((float)(total-wrongs)/total)*100)+"%"
);
if (((int)(((float)(total-wrongs)/total)*100))> 0.6)
JOptionPane.showMessageDialog(null,"You Passed!");
else {
JOptionPane.showMessageDialog(null,"You are NOT Smarter than a 5th Grader");
}
System.exit(0);
}
}
class Question extends JPanel {
int correctAns;
MultipleChoice Choices;
int selected;
boolean used;
//questions
JPanel qPanel=new JPanel();
//answers
JPanel aPanel=new JPanel();
JRadioButton[] responses;
//bottom
JPanel botPanel=new JPanel();
JButton next=new JButton("Next");
JButton finish=new JButton("Finish");
private String question;
private String[] answers;
private String ans;
public Question(String possibleQuestion ,String[] possibleAnswer , String correctAnswer){ //constructor
this.Choices=Choices;
question = possibleQuestion;
answers = possibleAnswer;
ans = correctAnswer;
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
//question
qPanel.add(new JLabel(question));
add(qPanel);
//answer
responses=new JRadioButton[answers.length];
//display possible answer and answers
aPanel.add(responses[i]);
add(aPanel);
//bottom
next.addActionListener(this);
finish.addActionListener(this);
botPanel.add(next);
botPanel.add(finish);
add(botPanel);
}
public Question(String possibleQuestion ,String[] possibleAnswer){ //constructor overloading
question = possibleQuestion;
answers = possibleAnswer;
}
String getquestion(){ //getter
return question;
}
void setquestion(String str){ //setter
question = str;
}
String[] getanswers(){ //getter
return answers;
}
void setanswers(String[] str2){ //setter
answers = str2;
}
String getans(){ //getter
return ans;
}
void setans(String str3){ //setter
ans = str3;
}
public void actionPerformed(ActionEvent e){
Object src=e.getSource();
//next button
if(src.equals(next)){
if(selected==correctAns){
used=true;
Choices.next();
}
}
//finish button
if(src.equals(finish)){
Choices.showSummary();
}
}
}
New Revisions So after I create the interface and implement it. I somehow can't seem to display the question or options. the JButton doens't seems to work.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class MultipleChoice {
JPanel p=new JPanel();
CardLayout cards=new CardLayout();
int numQs;
int wrongs=0;
int total=0;
public static void main(String[] args){
new MultipleChoice();
}
public MultipleChoice(){
List<Question> questions = new ArrayList<>();
questions.add(new Question("Which of the following is NOT one of the 5 great lakes?",new String[]{"Lake Mead","Lake Huron","Lake Michigan","Lake Erie"}, "Lake Mead"));
questions.add(new Question("What is the Capital of Colorado?",new String[]{"Boulder","Aspen","Denver","Cheyenne"},"Denver"));
questions.add(new Question("Each side of a baseball diamond is 90 feet in length. How far is it around the Baseball Diamond?",new String[]{"270","360","180","390"},"360"));
questions.add(new Question("What color do you get when you combine an equal amount of red paint with an equal amount of yellow paint?",new String[]{"Blue","Orange","Green","Pink"},"Orange"));
questions.add(new Question("How many sides does a trapezoid have?",new String[]{"3","4","5","6"},"2"));
questions.add(new Question("Which is a simile?",new String[]{"My sister is cute like a bunny","My mom has a manly snore","My dad is better than yours"},"My sister is cute like a bunny"));
questions.add(new Question("Polar bears eat penquins?",new String[]{"True","False"},"True"));
JFrame frame = new JFrame("Are you Smarter than a 5th Grader?");
frame.setResizable(true);
frame.setSize(500,400);
frame.add(new QuizPane(questions));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public class QuizPane extends JPanel {
private CardLayout cardLayout;
private int currentQuestion;
private JButton next;
private List<Question> question;
private JPanel panelOfQuestions;
public QuizPane(List<Question> question) {
this.question = question;
cardLayout = new CardLayout();
panelOfQuestions = new JPanel(cardLayout);
JButton start = new JButton("Start");
start.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
currentQuestion = -1;
next();
}
});
JPanel filler = new JPanel(new GridBagLayout());
filler.add(start);
panelOfQuestions.add(filler, "start");
for (int index = 0; index < question.size(); index++) {
QuestionInterface quiz = question.get(index);
QuestionPane pane = new QuestionPane(quiz);
panelOfQuestions.add(pane, Integer.toString(index));
}
panelOfQuestions.add(new JLabel("The quiz is over"), "last");
currentQuestion = 0;
cardLayout.show(panelOfQuestions, "start");
setLayout(new BorderLayout());
add(panelOfQuestions);
JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
next = new JButton("Next");
buttonPane.add(next);
next.setEnabled(false);
add(buttonPane, BorderLayout.SOUTH);
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
next();
}
});
}
public void next(){
if (currentQuestion >= question.size()) {
cardLayout.show(panelOfQuestions, "last");
next.setEnabled(false);
// You could could loop through all the questions and tally
// the correct answers here
}
else {
cardLayout.show(panelOfQuestions, Integer.toString(currentQuestion));
next.setText("Next");
next.setEnabled(true);
}
}
/*public void showSummary(){ // try to get to show summary after the quiz
JOptionPane.showMessageDialog(null,"All Done :), here are your results"+
"\nNumber of incorrect Answers: \t"+wrongs+
"\nNumber of Correct Answers: \t"+(total-wrongs)+
"\nPercent Correct: \t\t"+(int)(((float)(total-wrongs)/total)*100)+"%"
);
if (((int)(((float)(total-wrongs)/total)*100))> 0.6)
JOptionPane.showMessageDialog(null,"You Passed!");
else {
JOptionPane.showMessageDialog(null,"You are NOT Smarter than a 5th Grader");
}
System.exit(0);
}*/
}
public interface QuestionInterface {
public String getquestion();
public String[] getOptions();
public String getAnswer();
public String getUserResponse();
public void setUserResponse(String response);
public boolean isCorrect();
}
public class Question implements QuestionInterface {
private String possibleQuestion;
private String[] Options;
public String correctAnswer;
private String userResponse;
public Question(String possibleQuestion ,String[] Options , String correctAnswer){ //constructor
this.possibleQuestion = possibleQuestion;
this.Options = Options;
this.correctAnswer = correctAnswer;
}
public Question(String possibleQuestion ,String[] possibleAnswer){ //constructor overloading
this.possibleQuestion = possibleQuestion;
this.Options = Options;
}
public String getquestion(){ //getter
return possibleQuestion;
}
void setquestion(String str){ //setter
possibleQuestion = str;
}
public String[] getOptions(){ //getter
return Options;
}
void setanswers(String[] str2){ //setter
Options = str2;
}
public String getAnswer(){ //getter
return correctAnswer;
}
void setans(String str3){ //setter
correctAnswer = str3;
}
public String getUserResponse() {
return userResponse;
}
public void setUserResponse(String response) {
userResponse = response;
}
public boolean isCorrect() {
return getAnswer().equals(getUserResponse());
}
}
public class QuestionPane extends JPanel {
private QuestionInterface question;
public QuestionPane(QuestionInterface question) {
this.question = question;
setLayout(new BorderLayout());
JLabel prompt = new JLabel("<html><b>" + question.getquestion() + "</b></html>");
prompt.setHorizontalAlignment(JLabel.LEFT);
add(prompt, BorderLayout.NORTH);
JPanel guesses = new JPanel(new GridBagLayout());
guesses.setBorder(new EmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.WEST;
List<String> options = new ArrayList<>(Arrays.asList(question.getOptions()));
options.add(question.getAnswer());
Collections.sort(options);
ButtonGroup bg = new ButtonGroup();
for (String option : options) {
JRadioButton btn = new JRadioButton(option);
bg.add(btn);
guesses.add(btn, gbc);
}
add(guesses);
}
public QuestionInterface getQuestion() {
return question;
}
public class ActionHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
getQuestion().setUserResponse(e.getActionCommand());
}
}
}
}
Welcome to the wonderful world of why you shouldn't extend from top level containers (or at least one of the reasons)
Start by extending
MultipleChoice
from aJPanel
instead of aJDialog
. This will produce a number of compiler errors...setModal(true);
Kind of pointless on a panel, so you can get rid of itgetContentPane()
, well, a panel doesn't have aJRootPane
so it doesn't have a content pane. You can usethis
insteaddispose
. Well, a panel isn't a window, so it can't be "disposed" per se. I would personally replace this with some kind of Observer Pattern, which would provide notifications when the state of the quiz has changed (like the it has been completed) so that the caller can deal with it in the way they want to. The point is, don't make assumptions about how people might like to use your componentpack
, well, this goes in the same boat as the others, so you can just get rid of it.setVisible
, well, Swing components are visible by default, so it's probably a bit pointless.Know, all you need to do is create an instance of your
MultipleChoice
panel and add it to what ever container you want.This is a layout issue. In your case, I would use compound layout, maybe using a
FlowLayout
for the buttons and aBorderLayout
for the "questions" and button panel (in theSOUTH
position).Incidentally, you should probably be using a
CardLayout
to show the questions, which I presented in this surprisingly similar question.Collections.shuffle(questions);
is probably the easiest solution I can think of. Once you call it, theList
will be randomly shuffled.Well, there goes the context of the original answer...
List
as if it was an array, that's now how they work.Question
(JPanel
) doesn't implementActionListener
sonext.addActionListener(this);
isn't going to workaPanel.add(responses[i]);
in a loop and create theJRadioButton
s, which all should be added to the sameButtonGroup
Choices
in isQuestion
never assigned a value and will generate aNullPointerException
. I'd be worried about exposingMultipleChoice
directly and would personally use ainterface
which provided the contract of what could be executed against the classList
ofJRadioButton
, one for each possible answer and one for the correct answer, I would the useCollection.shuffle
to shuffle thisList
in some random way and then add the buttons to theQuestion
panel