英文:
Writing a code for the game to be restarted using a JoptionPane in java
问题
在编写问答游戏的代码时,我使用了 JOptionPane 来设置点击"是"并允许游戏重新开始。使用下面的代码,我能够获得一个新窗口显示结果,并提供重新开始游戏或退出的选项。下面是代码部分:
for (int i = 0; i < question.getAnswers().length; i++) {
answersButtons[i] = new JButton(String.valueOf((char) ('A' + i))); // 这将设置按钮的文本为A、B、C、D
answersButtons[i].addActionListener(e -> { // 使用Java 8 lambda的ActionListener
if (e.getActionCommand().charAt(0) - 'A' == question.getCorrectAnswer() - 1) { // 在这里检查点击的按钮是否是正确答案,将文本从A-D转换为0-3,然后与问题模型的索引-1进行比较
correctAnswers++; // 正确答案加1
answerLabels[e.getActionCommand().charAt(0) - 'A'].setBackground(Color.GREEN); // 如果答案正确,将背景颜色设置为绿色
} else {
answerLabels[e.getActionCommand().charAt(0) - 'A'].setBackground(Color.RED); // 否则设置为红色
}
if (currentQuestion == totalQuestions - 1) { // 如果达到问题的末尾,显示结果屏幕
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);
// 重置所有内容并再次显示您的GUI
} else {
frame.dispose(); // 如果用户选择不重试,关闭窗口。
}
} else {
timer.start(); // 启动显示结果的计时器,持续半秒钟。
}
});
}
完整代码如下:
// 请注意,这只是代码的一部分,我在此处提供了关键部分的翻译。如果需要完整的代码,请告诉我。
// 其他代码...
请注意,这只是代码的一部分翻译。如果您需要完整的代码或有其他问题,请随时告诉我。
英文:
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;
}
}
答案1
得分: 1
如果您想使用新的JFrame实例重新启动游戏,请使用以下代码:
if (input == JOptionPane.YES_OPTION) {
frame.dispose();
MainGame mainGame = new MainGame();
mainGame.createAndShowGUI(); // 确保您将方法访问权限更改为public
} else {
frame.dispose(); // 如果用户表示不想重试,关闭窗口。
}
如果您想重新启动游戏,但要使用现有的JFrame实例,您需要稍微修改您的代码:
- 分别创建JFrame(您可以保持原样)
- 将JFrame的子组件的创建(卡片、面板等)分离到不同的方法中,并将JFrame实例作为参数传递。
- 在结果确认对话框中编写以下代码:
if (input == JOptionPane.YES_OPTION) {
frame.getContentPane().removeAll();
// 调用如上所述的方法#2
} else {
frame.dispose(); // 如果用户表示不想重试,关闭窗口。
}
英文:
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:
-
Create the JFrame separately (you may keep it as it is)
-
Separate the creation of child components of the JFrame (Cards, Panels etc) in a different method. Pass the JFrame instance as parameter.
-
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. }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论