我在做一个 数学测验游戏 其中,问题是随机产生的,用户必须要有 在jtextfield中填写答案. 然后,当用户按 回车键 到 对答జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ 下一个问题 也将以同样的形式加载(显示在jlabel中)为 10轮.
但我有一个问题,当我使用for循环(不断生成问题并提示用户回答10轮)时,它的作用是 不 允许用户在第一个问题后的文本字段中输入答案。 它跳过了jtextfield的gettext(),并在文本字段留有空白时重复空文本字段信息。当输入其他数字以外的输入时,重复的 catch numberformatexception 消息也是一样。我如何使gui 再次让用户在文本框中输入 每一轮都有错误的输入?
我已经通过类似的标签在这里,我已经尝试阅读线程的解决方案,因为一些建议在那些,但我真的是新的,所以我真的很感激的帮助。如果有一个简单的解决方案,我真的很想听到它,因为我已经卡了这么久。非常感谢您的帮助。
下面是代码。
变量
double answer=0; //correct answer
double playerans=0d;
String ans;
String mOperation, question;
int no1, no2;
int rounds = 10;
public Game() {
initComponents();
this.EasyQuestion();
}
回车键 /问题
private void enterbtnActionPerformed(java.awt.event.ActionEvent evt) {
//needs to get user fill textfield then load next question
for (int i=0; i<rounds; ++i)
{
roundlabel.setText(" " + String.valueOf(i + 1));
boolean valid=false;
ans = ansfield.getText().trim();
if (!ansfield.getText().equals(""))
{
do
{
try
{
playerans = Double.parseDouble(ans); //convert to double
//check player answer- if (Math.abs(Double.parseDouble(answer) - q.answer) <= 0.01)
valid = true;
}catch (NumberFormatException e){ //other input other than integers
JOptionPane.showMessageDialog(null, "Please enter number only");
ansfield.setText("");
valid = false;
//thread sleep
}
} while (!valid);
if (Math.abs(Double.parseDouble(ans) - this.answer) <= 0.01) {//for correct answer
JOptionPane.showMessageDialog(null, "You got it right!"); //mesage to inform player
}
else //wrong answers
{
JOptionPane.showMessageDialog(null, "You got it wrong!"); //mesage to inform player
}
}
else
{
JOptionPane.showMessageDialog(null, "Empty field");//
}
//generate next question
EasyQuestion();
/*open end game form
this.close();
EndGame end = new EndGame();
end.setVisible(true);
*/
}//end for
}
数学题生成
//generate math question for easy level
public double EasyQuestion()
{
//call method to generate random integers
no1 = this.createNum(100); //set range to 100
no2 = this.createNum(100);
//generate random 4 math operations
int math = createNum (4);
switch (math){
case 0:
mOperation= "+";
this.answer = no1 + no2;
break;
case 1:
mOperation = "-";
this.answer = this.no1 - this.no2;
break;
case 2:
mOperation = "*";
this.answer = this.no1 * this.no2;
break;
default:
mOperation = "/";
//to prevent math error
while (no2 == 0) {
this.no2 = this.createNum(100);
}
this.answer = 1.0 * this.no1 /this.no2; //to make double num type
break;
}
//display questions
question = (no1 + " " + mOperation + " " + no2 + " = ?");
qlabel.setText(question);
ansfield.setText("");
return this.answer;
}
//generate random number for math integers
public int createNum (int range)
{
//create instance class Random
Random rand = new Random();
int generate = rand.nextInt(range);
return generate;
}
这不是事件驱动程序的工作方式,你要做的是把线性控制台编程塞进事件驱动的GUI中。循环实际上是阻塞了Swing事件线程("事件派遣线程或EDT),这可能会使你的程序冻结和无用。
相反,让你的程序更多的是事件驱动,更多的是 "有状态的",它根据关键的 "状态 "字段variables的状态来改变它对事件的响应。
在这种情况下,你可以给用户提供10个JTextFields,并要求他们在这些字段中输入数据,直到所有字段都填满了适当的数据才允许进一步的操作--例如,有一个 "提交 "的JB按钮是被禁用的,给JTextFields提供一个DocumentListener,它可以在文档发生变化时随时检查内容,只有当所有的输入都是有效的时候才启用提交按钮。
或者你可以有一个int计数器变量,一个String数组和一个JTextField,每次用户提交文本时,递增计数器并将String放到数组(或ArrayList)的适当位置......。
在这种情况下,你可能会有一个非GUI的Question类,其中包含一个单一的问题文本和它的答案。然后你会创建一个 List<Question>
questions = new ArrayList<>();`然后利用我上面说的index int字段,在ActionListener中,接受输入,然后前进显示下一个问题并显示,同样完全摆脱for循环。
不过最重要的是,你需要离开线性编程模式,进入事件驱动的思路。
举个例子
在下面的程序中,我用一个叫 "int "的状态字段来跟踪我问的是哪个问题 index
. 在ActionListener中,我检查了答案是否正确,然后我通过 index++
. 然后,我通过比较问题数组列表的索引来检查是否还有更多的问题。size()
财产,......。
import java.util.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
public class MultipleQuestions extends JPanel {
private List<Question> questions;
private JLabel questionLabel = new JLabel();
private JLabel resultLabel = new JLabel(" ");
private JTextField answerField = new JTextField(20);
private JButton submitButton = new JButton("Submit");
private int index = 0;
public MultipleQuestions(List<Question> questions) {
this.questions = questions;
ActionListener listener = e -> submitListener();
submitButton.addActionListener(listener);
answerField.addActionListener(listener);
submitButton.setMnemonic(KeyEvent.VK_S);
questionLabel.setText(questions.get(index).getQuestion());
JPanel questionPanel = new JPanel();
questionPanel.setBorder(BorderFactory.createTitledBorder("Question"));
questionPanel.add(questionLabel);
JPanel resultPanel = new JPanel();
resultPanel.setBorder(BorderFactory.createTitledBorder("Result"));
resultPanel.add(resultLabel);
JPanel answerPanel = new JPanel();
answerPanel.setBorder(BorderFactory.createTitledBorder("Answer"));
answerPanel.add(answerField);
answerPanel.add(submitButton);
setLayout(new BorderLayout());
add(questionPanel, BorderLayout.PAGE_START);
add(resultPanel, BorderLayout.PAGE_END);
add(answerPanel);
}
private void submitListener() {
String answerText = answerField.getText().trim();
if (answerText.equals(questions.get(index).getAnswer())) {
resultLabel.setText("Correct");
} else {
resultLabel.setText("incorrect");
}
answerField.selectAll();
answerField.requestFocusInWindow();
index++;
if (index >= questions.size()) {
resultLabel.setText("All Done");
submitButton.setEnabled(false);
answerField.setEnabled(false);
} else {
questionLabel.setText(questions.get(index).getQuestion());
}
}
public static void main(String[] args) {
List<Question> questions = Arrays.asList(
new Question("What is 1 + 1", "2"),
new Question("What is 1 + 2", "3"),
new Question("What is 1 + 3", "4"),
new Question("What is 1 + 4", "5"),
new Question("What is 1 + 5", "6"),
new Question("What is 1 + 6", "7")
);
MultipleQuestions multipleQuestions = new MultipleQuestions(questions);
JFrame frame = new JFrame("Mult Q's");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(multipleQuestions);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class Question {
private String question;
private String answer;
public Question(String question, String answer) {
this.question = question;
this.answer = answer;
}
public String getQuestion() {
return question;
}
public String getAnswer() {
return answer;
}
}