user14004788
user14004788

Reputation: 11

Writing a code for the game to be restarted using a JoptionPane in java

While I was writing the code for the quiz game, I used a JOptionPane setting it to click a yes and allowing the game to restart. With the below code, I was able to get a new window showing the result and giving options to wether cohoe between to reset the game or to exit. This is the code down below and by adding 'frame.setVisible(isEnabled));', I were able to get rid of the new window by clicking the reset button but the game window only showed me the very last page of the quiz, not allowing me to do the quiz again. I want the game to be started at its very first page , what should I do in this case?

  for (int i = 0; i < question.getAnswers().length; i++) {
        answersButtons[i] = new JButton(String.valueOf((char) ('A' + i))); // This will set the buttons text to A, B, C, D
        answersButtons[i].addActionListener(e -> { //ActionListener using Java 8 lambdas
            if (e.getActionCommand().charAt(0) - 'A' == question.getCorrectAnswer() - 1) { //Here we check if the button clicked was the one with the correct answer, converting the text from A-D to 0-3 and compare it to the index - 1 from the question model
                correctAnswers++; //Increase the correctAnswer + 1
                answerLabels[e.getActionCommand().charAt(0) - 'A'].setBackground(Color.GREEN); //Set the background color to green if it was correct
            } else {
                answerLabels[e.getActionCommand().charAt(0) - 'A'].setBackground(Color.RED); //Or red otherwise
            }
            if (currentQuestion == totalQuestions - 1) { //If we reach the end of questions, show the results screen
                int input = JOptionPane.showConfirmDialog(pane, new ResultsPane(correctAnswers, totalQuestions), "Results", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null);
                
                if (input == JOptionPane.YES_OPTION) {
                    
                    frame.setVisible(isEnabled());
                    frame.setVisible(true);
                    //Reset everything and show your GUI again
                } else {
                    frame.dispose(); //If user says they don't want to retry, dispose the frame.
                }
            } else {
                timer.start(); //Start the timer that will display the results for half a second.
            }
        });
    }

Full code below :

     import java.awt.BorderLayout;
     Import java.awt.CardLayout;
     import java.awt.Color;
     import java.awt.Dimension;
     import java.awt.FlowLayout;
      import java.awt.Font;
      import java.awt.Window;
     import java.awt.event.ActionEvent;
       import java.awt.event.ActionListener;
   import java.text.SimpleDateFormat;
   import java.util.ArrayList;
   import java.util.List;

 import javax.swing.BoxLayout;
 import javax.swing.JButton;
 import javax.swing.JComponent;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.RootPaneContainer;
 import javax.swing.SwingConstants;
 import javax.swing.SwingUtilities;
 import javax.swing.Timer;
 import javax.swing.UIManager;

  // main class, contains the CardLayout
  public class MainGamw {

    int c = 15;
    private JFrame frame;

    private QuestionPane[] cards;
    private JPanel pane;
    private CardLayout cl;

    private JLabel timerLabel;
    private JLabel timeNumber;

    private List<QuizQuestion> questions;
    private Timer temporaryTimer;

    public static void main(String[] args) {
        // place the program on the EDT using Java 8 lambdas
        SwingUtilities.invokeLater(new MainGamw()::createAndShowGUI);
    }


private void createAndShowGUI() {
    frame = new JFrame(getClass().getSimpleName()); //the class name and set it as the frame's title
    frame.getContentPane().setBackground(new Color(204,229,255));
    frame.setPreferredSize(new Dimension(600,350));
    frame.pack();
    
    cl = new CardLayout(); //Create a new CardLayout
    
    pane = new JPanel(cl); //Set the CardLayout to this JPanel
    pane.setBackground(new Color(204,229,255));
    pane.setVisible(true);
   
    temporaryTimer = new Timer(500, event -> { //The timer to show the result of the answer for half second before switching to the new one.
        c--;
        timeNumber.setText(String.valueOf(c));
        cl.next(pane); //This moves the CardLayout to the next one
        
        temporaryTimer.stop(); //We stop this timer when we switch to the next card.
    });
    
    generateQuestionsAndAnswers(); //We populate the model of questions with their answers here.
    
    cards = new QuestionPane[questions.size()];
    for (int i = 0; i < cards.length; i++) {
        cards[i] = new QuestionPane(questions.get(i), i, pane, cl, cards.length, frame, temporaryTimer); //We create a new QuestionPane and send some information as parameters
        
        pane.add(cards[i], "question" + i); //We add the card to the CardLayout pane
    }
    
    timerLabel = new JLabel("  Time: ");
    timerLabel.setFont(new Font("PT Serif",Font.PLAIN,16));
    
    timeNumber = new JLabel();
    timeNumber.setFont(new Font("PT Serif",Font.PLAIN,16));
    timeNumber.setText(String.valueOf(c));
    
    UIManager.put("OptionPane.okButtonText", "Start Quiz"); //We change the "OK" from the JOptionPane button to "Start Quiz"
    int option = JOptionPane.showConfirmDialog(frame, new JLabel("Click button to start quiz"), 
                                            "Welcome", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null);
    if (option == JOptionPane.OK_OPTION) {
        
        //Start your timer for the first question
    }

    frame.add(pane); //We add the CardLayout pane to our JFrame's CENTER position
    frame.add(timerLabel, BorderLayout.SOUTH); //And the timerLabel at the bottom
    frame.add(timeNumber, BorderLayout.WEST);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true); //
}



private Object size(int i, int j) {
    // TODO Auto-generated method stub
    return null;
}


  //We create an ArrayList of QuizQuestion that each has their own    question, the possible answers and the correct answer (index + 1)
private void generateQuestionsAndAnswers() {
    questions = new ArrayList<>();
    questions.add(new QuizQuestion("Select the official name of the coronavirus.", new String[] {"COVID-19","Sars-CoV-2","Zaire ebolavirus","Influenza"}, 1));
    questions.add(new QuizQuestion("When did the corona virus first ecountered?", new String[] {"2018","2020","2017","2019"}, 4));
    questions.add(new QuizQuestion("What is the percentage of people recovering from the coronavirus?", new String[] {"63%","71%","80%","76%"}, 3));
   
    questions.add(new QuizQuestion("Which below is NOT the symptom of coronavirus?", new String[] {"Fever","Blurred vision","Dry Cough","Nasal Congestion"}, 2));
    questions.add(new QuizQuestion("Which part of the human body does the coronavirus attach itself to?", new String[] {"Red Blood Cells", "Antigens", "White Blood Cells", "Ace-2 recpetors in the airways"}, 4));
    questions.add(new QuizQuestion("How many hour can the coronavirus survive on plastic and stainless steel surfaces?", new String[] {"4-8 hours", "72 hours and more", "45-60 hours", "90 hours and more" }, 2));

    questions.add(new QuizQuestion("Which human organs in the body does the coronavirus attack?", new String[] {"Liver", "Lungs", "Heart", "Kidney" }, 2));
    questions.add(new QuizQuestion("How large is the coronavirus?", new String[] {"8000 billionths of metre in diameter", "800 billionths of metre in diameter","80 billionths of metre in diameter","8 billionths of metre in diameter" }, 3));
    questions.add(new QuizQuestion("Which is a safe distance to stay apart from people? ", new String[] {"3 feet(1 meter)", "2 feet(60 cm)", "1 foot (30cm)", "4.2 feet(1.3 meter)"}, 1));
    
    questions.add(new QuizQuestion("Who has the highest risk of getting infected by coronvirus?", new String[] {"Children", "Pregnant Women", "People over 60 years of age", "30-40 years agr of men"}, 3));
    questions.add(new QuizQuestion("When should face masks be worn?", new String[] {"Public Transport", "Confined or Crowed spaces", "Small restaurants or shops", "All of the above"}, 4));
    questions.add(new QuizQuestion( "Which is more effective for removing the coronavirus from your hands?", new String[] {"Soap and water", "Alcohol-based hand sanitiser","Detergent", "Face cleanser"}, 1));
    
    questions.add(new QuizQuestion("Which industry includes workers with increased exposure-risk?", new String[] {"Health care", "Airline operations", "Waste management", "All of the above"}, 4));
    questions.add(new QuizQuestion("What is the period of quartine?", new String[] {"21 days","7 days", "14 days", "6 days"}, 3));
    questions.add(new QuizQuestion("What is the name of the city where coronavirus was first detected?", new String[] {"Wuhan", "Hubei", "Hunan","Shanghai"}, 1));   
}
 }


  @SuppressWarnings("serial")
   class ResultsPane extends JPanel { //This is a class that will   create a simple JPanel with vertical alignment to add the number of correct answers, accuracy and a text for the user if they want to retry
public ResultsPane(int correctAnswers, int totalQuestions) {
    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    float percentage = ((float) (correctAnswers) / (float) (totalQuestions)) * 100;
    
    add(new JLabel("Correct Answers: " + correctAnswers + " / " +   totalQuestions));
    add(new JLabel("Accuracy: " + percentage + "%"));
    add(new JLabel("Want to Retry?"));
   }
 }

@SuppressWarnings("serial")
class QuestionPane extends JPanel { //This is the pane in which each   card will be displayed
private JButton[] answersButtons; //Array of buttons for the answers instead of 4 individual buttons

private JLabel questionLabel;
private JLabel questionNumber;
private JLabel[] answerLabels; //Same for the labels

private static int correctAnswers = 0; //This is static to count all the correct answers in all the instances

 public QuestionPane(QuizQuestion question, int currentQuestion, JPanel pane, CardLayout cl, int totalQuestions, JFrame frame, Timer timer) { //Probably this isn't the most elegant solution to send multiple objects as parameters here, as it makes the program tightly coupled.
    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    
    questionNumber = new JLabel("Question " + (currentQuestion + 1), SwingConstants.LEFT);
    questionNumber.setFont(new Font("PT Serif",Font.BOLD,16));
    questionNumber.setHorizontalAlignment(JLabel.LEFT);
    
    //We set the question number on top and center the text
    
    questionLabel = new JLabel(question.getQuestion()); 
    questionLabel.setFont(new Font("PT Serif",Font.BOLD,15));
    questionLabel.setAlignmentX(LEFT_ALIGNMENT);
    
    // We set the question text to this label
    answerLabels = new JLabel[question.getAnswers().length]; 
    
    //We create our array of 4 labels and 4 buttons below
    
    answersButtons = new JButton[question.getAnswers().length];
    
    
    for (int i = 0; i < question.getAnswers().length; i++) {
        answersButtons[i] = new JButton(String.valueOf((char) ('A' + i))); // This will set the buttons text to A, B, C, D
        answersButtons[i].addActionListener(e -> { //ActionListener using Java 8 lambdas
            if (e.getActionCommand().charAt(0) - 'A' == question.getCorrectAnswer() - 1) { //Here we check if the button clicked was the one with the correct answer, converting the text from A-D to 0-3 and compare it to the index - 1 from the question model
                correctAnswers++; //Increase the correctAnswer + 1
                answerLabels[e.getActionCommand().charAt(0) - 'A'].setBackground(Color.GREEN); //Set the background color to green if it was correct
            } else {
                answerLabels[e.getActionCommand().charAt(0) - 'A'].setBackground(Color.RED); //Or red otherwise
            }
            if (currentQuestion == totalQuestions - 1) { //If we reach the end of questions, show the results screen
                int input = JOptionPane.showConfirmDialog(pane, new ResultsPane(correctAnswers, totalQuestions), "Results", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null);
                
                if (input == JOptionPane.YES_OPTION) {
                    
                    frame.setVisible(isEnabled());
                    frame.setVisible(true);
                    //Reset everything and show your GUI again
                } else {
                    frame.dispose(); //If user says they don't want to retry, dispose the frame.
                }
            } else {
                timer.start(); //Start the timer that will display the results for half a second.
            }
        });
    }
    
    add(questionNumber, BorderLayout.EAST); //Add the question number
    add(questionLabel, BorderLayout.EAST); //The question text
    
    for (int i = 0; i < question.getAnswers().length; i++) {
        JPanel answerPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); //Create a new JPanel for each label and button and make them left aligned
        
        answerPane.add(answersButtons[i]); //Add every button
        answerLabels[i] = new JLabel(question.getAnswers()[i]);     //Create a new label with each answer's text
        answerLabels[i].setOpaque(true); //Make them opaque (for the background colors later)
        answerPane.add(answerLabels[i]); //And add them to the pane
        
        add(answerPane); //Then add the pane to the wrapping pane
    }
}
}




 //A simple model for your questions.
 class QuizQuestion {
private String question;
private String[] answers;
private int correctAnswer;

public QuizQuestion(String question, String[] answers, int correctAnswer) {
    super();
    this.question = question;
    this.answers = answers;
    this.correctAnswer = correctAnswer;
}

public String getQuestion() {
    return question;
}

public void setQuestion(String question) {
    this.question = question;
}

public String[] getAnswers() {
    return answers;
}

public void setAnswers(String[] answers) {
    this.answers = answers;
}

public int getCorrectAnswer() {
    return correctAnswer;
}

public void setCorrectAnswer(int correctAnswer) {
    this.correctAnswer = correctAnswer;
}
}

Upvotes: 0

Views: 284

Answers (1)

Arindam Roy
Arindam Roy

Reputation: 111

If you want to restart the game with a new JFrame instance, following code will help:

if (input == JOptionPane.YES_OPTION) {
    frame.dispose();

    MainGamw mainGame = new MainGamw();
    mainGame.createAndShowGUI(); // Make sure you change method access to public

} else {
    frame.dispose(); //If user says they don't want to retry, dispose the frame.
}

If you want to restart your game, with the existing JFrame instance, you need to modify your code slightly:

  1. Create the JFrame separately (you may keep it as it is)

  2. Separate the creation of child components of the JFrame (Cards, Panels etc) in a different method. Pass the JFrame instance as parameter.

  3. Write following code, at result Confirm Dialog:

    if (input == JOptionPane.YES_OPTION) {
        frame.getContentPane().removeAll();
        // Call the method as described #2
    
    } else {
        frame.dispose(); //If user says they don't want to retry, dispose the frame.
    }
    

Upvotes: 1

Related Questions