[英]Java Swing: How to allow user enter Jtextfield again when wrong input?
我正在做一个数学问答游戏,其中问题是随机生成的,用户必须在 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”),这会使您的程序冻结且无用。
相反,让您的程序更加事件驱动和更加“有状态”,它会根据关键“状态”字段/变量的 state 更改它对事件的响应方式。
在这种情况下,您可以向用户提供 10 个 JTextField 并要求他们在字段中输入数据,并且在所有字段都填充了适当的数据之前不允许进一步的操作——例如,有一个禁用的“提交”JButton,给JTextFields 是一个 DocumentListener,它可以在文档更改时检查内容,并且只有在所有输入都有效时才启用提交按钮。
或者您可以有一个 int 计数器变量、一个字符串数组和一个 JTextField,并且每次用户提交文本时,递增计数器并将字符串放入数组(或 ArrayList)中的适当 position 中...
在这种情况下,您可能会有一个非 GUI 问题 class,它包含一个问题文本及其答案。 然后,您将创建一个List<Question>
questions = new ArrayList<>();`,然后在 ActionListener 中使用我上面描述的 index int 字段,接受输入,然后继续显示下一个问题并显示它,再次完全摆脱 for 循环。
但最重要的是,您需要离开线性编程模式并进入事件驱动的思维模式。
例如:
在下面的程序中,我使用名为index
的 int state 字段来跟踪我要问的问题。 在 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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.