[英]Writing a code for the game to be restarted using a JoptionPane in java
在我為問答游戲編寫代碼時,我使用 JOptionPane 將其設置為單擊“是”並允許游戲重新啟動。 使用下面的代碼,我能夠獲得一個新的 window 顯示結果並提供選項讓 cohoe 重置游戲或退出。 這是下面的代碼,通過添加“frame.setVisible(isEnabled));”,我可以通過單擊重置按鈕擺脫新的 window,但游戲 window 只向我展示了測驗的最后一頁,不允許我再做測驗。 我希望游戲從第一頁開始,在這種情況下我應該怎么做?
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.
}
});
}
完整代碼如下:
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;
}
}
如果您想使用新的 JFrame 實例重新啟動游戲,以下代碼將有所幫助:
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.
}
如果你想重啟你的游戲,使用現有的 JFrame 實例,你需要稍微修改你的代碼:
單獨創建 JFrame(您可以保持原樣)
以不同的方法分離 JFrame(卡片、面板等)的子組件的創建。 將 JFrame 實例作為參數傳遞。
在結果確認對話框中編寫以下代碼:
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. }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.