当日总结
用java实现四则预算随机出题的界面化
import java.awt.;
import java.util.;
import javax.swing.*;
//import java.awt.List;
import java.util.List;
import javax.swing.Timer;
public class MathQuizWithTimer extends JFrame {
private Random random = new Random();
private int totalQuestions = 30;
private int correctCount = 0;
// 存储题目信息的列表
private List<Question> questions = new ArrayList<>();
// 计时相关
private Timer timer;
private long startTime;
private JLabel timeLabel;
private int secondsElapsed = 0;
// GUI组件
private JPanel questionsPanel;
private JScrollPane scrollPane;
private JButton submitButton;
private JLabel resultLabel;
public MathQuizWithTimer() {
// 设置窗口基本属性
setTitle("数学测验 - 计时版");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setLocationRelativeTo(null); // 窗口居中
// 初始化界面
initUI();
// 先初始化计时器(关键修正)
initTimer();
// 再生成题目(此时timer已被初始化)
generateAllQuestions();
// 显示所有题目
displayAllQuestions();
}
private void initUI() {
// 主面板使用边界布局
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 顶部:计时标签和标题
JPanel topPanel = new JPanel(new BorderLayout());
JLabel titleLabel = new JLabel("数学测验", SwingConstants.CENTER);
titleLabel.setFont(new Font("宋体", Font.BOLD, 20));
topPanel.add(titleLabel, BorderLayout.NORTH);
// 计时标签
timeLabel = new JLabel("用时: 00:00", SwingConstants.CENTER);
timeLabel.setFont(new Font("宋体", Font.PLAIN, 16));
timeLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
topPanel.add(timeLabel, BorderLayout.SOUTH);
mainPanel.add(topPanel, BorderLayout.NORTH);
// 中间:题目区域
questionsPanel = new JPanel();
questionsPanel.setLayout(new GridLayout(0, 1, 5, 5)); // 垂直排列题目
scrollPane = new JScrollPane(questionsPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
mainPanel.add(scrollPane, BorderLayout.CENTER);
// 底部:提交按钮和结果
JPanel bottomPanel = new JPanel(new BorderLayout());
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
submitButton = new JButton("提交答案");
submitButton.setFont(new Font("宋体", Font.PLAIN, 16));
submitButton.addActionListener(e -> checkAllAnswers());
bottomPanel.add(submitButton, BorderLayout.NORTH);
resultLabel = new JLabel("", SwingConstants.CENTER);
resultLabel.setFont(new Font("宋体", Font.PLAIN, 16));
bottomPanel.add(resultLabel, BorderLayout.SOUTH);
mainPanel.add(bottomPanel, BorderLayout.SOUTH);
// 添加主面板到窗口
add(mainPanel);
}
// 初始化计时器
private void initTimer() {
timer = new Timer(1000, e -> {
secondsElapsed++;
updateTimeDisplay();
});
}
// 更新时间显示
private void updateTimeDisplay() {
int minutes = secondsElapsed / 60;
int seconds = secondsElapsed % 60;
timeLabel.setText(String.format("用时: %02d:%02d", minutes, seconds));
}
// 生成所有题目
private void generateAllQuestions() {
Set<String> usedQuestions = new HashSet<>();
questions.clear();
while (questions.size() < totalQuestions) {
int num1 = random.nextInt(100) + 1;
int num2 = random.nextInt(100) + 1;
int op = random.nextInt(4) + 1;
// 检查题目是否符合条件
if (!judge(num1, num2, op)) {
continue;
}
// 生成题目文本和正确答案
String questionText = "";
int correctAnswer = 0;
switch (op) {
case 1:
correctAnswer = num1 + num2;
questionText = num1 + "+" + num2 + "=";
break;
case 2:
correctAnswer = num1 - num2;
questionText = num1 + "-" + num2 + "=";
break;
case 3:
correctAnswer = num1 * num2;
questionText = num1 + "*" + num2 + "=";
break;
case 4:
correctAnswer = num1 / num2;
questionText = num1 + "/" + num2 + "=";
break;
}
// 检查题目是否重复
if (!usedQuestions.contains(questionText)) {
usedQuestions.add(questionText);
questions.add(new Question(questionText, correctAnswer));
}
}
// 开始计时
startTime = System.currentTimeMillis();
timer.start();
}
// 显示所有题目
private void displayAllQuestions() {
questionsPanel.removeAll();
for (int i = 0; i < questions.size(); i++) {
int questionNumber = i + 1;
Question question = questions.get(i);
// 每个题目使用一个面板显示
JPanel questionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
// 题号标签
JLabel numberLabel = new JLabel(questionNumber + ". ");
numberLabel.setFont(new Font("宋体", Font.PLAIN, 14));
// 题目文本
JLabel textLabel = new JLabel(question.getQuestionText());
textLabel.setFont(new Font("宋体", Font.PLAIN, 14));
textLabel.setPreferredSize(new Dimension(150, 20));
// 答案输入框
JTextField answerField = new JTextField(5);
answerField.setFont(new Font("宋体", Font.PLAIN, 14));
answerField.setName(String.valueOf(i)); // 用索引作为名称,方便后续获取
// 添加到题目面板
questionPanel.add(numberLabel);
questionPanel.add(textLabel);
questionPanel.add(answerField);
// 添加到总面板
questionsPanel.add(questionPanel);
}
// 刷新界面
questionsPanel.revalidate();
questionsPanel.repaint();
}
// 检查所有答案
private void checkAllAnswers() {
// 停止计时
timer.stop();
// 禁用提交按钮,防止重复提交
submitButton.setEnabled(false);
correctCount = 0;
List<String> wrongQuestions = new ArrayList<>();
// 遍历所有题目面板,获取答案
Component[] components = questionsPanel.getComponents();
for (Component component : components) {
if (component instanceof JPanel) {
JPanel questionPanel = (JPanel) component;
JTextField answerField = null;
JLabel textLabel = null;
// 从面板中找到输入框和题目标签
for (Component comp : questionPanel.getComponents()) {
if (comp instanceof JTextField) {
answerField = (JTextField) comp;
}
// 修正:先判断是JLabel,转换后再调用getText()
else if (comp instanceof JLabel) {
JLabel label = (JLabel) comp; // 强制转换为JLabel
if (!label.getText().endsWith(". ")) { // 现在可以安全调用getText()
textLabel = label;
}
}
}
if (answerField != null && textLabel != null) {
try {
// 获取题目索引
int index = Integer.parseInt(answerField.getName());
Question question = questions.get(index);
// 获取用户答案
String answerText = answerField.getText().trim();
if (answerText.isEmpty()) {
// 未答题视为错误
wrongQuestions.add((index + 1) + ". " + question.getQuestionText() + question.getCorrectAnswer());
answerField.setBackground(Color.PINK); // 错误答案标红
continue;
}
int userAnswer = Integer.parseInt(answerText);
// 检查答案
if (userAnswer == question.getCorrectAnswer()) {
correctCount++;
answerField.setBackground(Color.GREEN); // 正确答案标绿
} else {
wrongQuestions.add((index + 1) + ". " + question.getQuestionText() + question.getCorrectAnswer());
answerField.setBackground(Color.PINK); // 错误答案标红
}
} catch (NumberFormatException e) {
// 非数字输入视为错误
int index = Integer.parseInt(answerField.getName());
Question question = questions.get(index);
wrongQuestions.add((index + 1) + ". " + question.getQuestionText() + question.getCorrectAnswer());
answerField.setBackground(Color.PINK);
}
// 禁用输入框
answerField.setEnabled(false);
}
}
}
// 显示结果
double rate = (double) correctCount / totalQuestions * 100;
int wrongCount = totalQuestions - correctCount;
String result = String.format(
"答题完成!总用时: %02d:%02d,正确: %d 题,错误: %d 题,正确率: %.1f%%",
secondsElapsed / 60, secondsElapsed % 60,
correctCount, wrongCount, rate
);
resultLabel.setText(result);
// 显示错题列表
showWrongQuestionsDialog(wrongQuestions);
}
// 显示错题列表对话框
private void showWrongQuestionsDialog(List<String> wrongQuestions) {
JTextArea textArea = new JTextArea(10, 30);
textArea.setFont(new Font("宋体", Font.PLAIN, 14));
textArea.setEditable(false);
if (wrongQuestions.isEmpty()) {
textArea.setText("恭喜,没有错题!");
} else {
textArea.append("错题列表:\n");
for (String question : wrongQuestions) {
textArea.append(question + "\n");
}
}
JScrollPane scrollPane = new JScrollPane(textArea);
JOptionPane.showMessageDialog(
this, scrollPane, "测验结果", JOptionPane.INFORMATION_MESSAGE
);
}
// 判断题目是否符合条件
public static boolean judge(int x, int y, int op) {
switch (op) {
case 2: // 减法,确保结果非负
if (x < y) {
return false;
}
break;
case 3: // 乘法,确保结果不超过1000
if (x * y >= 1000) {
return false;
}
break;
case 4: // 除法,确保能整除且除数不为0
if (y == 0 || x % y != 0) {
return false;
}
break;
}
return true;
}
// 题目类,存储题目文本和正确答案
private class Question {
private String questionText;
private int correctAnswer;
public Question(String questionText, int correctAnswer) {
this.questionText = questionText;
this.correctAnswer = correctAnswer;
}
public String getQuestionText() {
return questionText;
}
public int getCorrectAnswer() {
return correctAnswer;
}
}
public static void main(String[] args) {
// 在事件调度线程中运行界面
SwingUtilities.invokeLater(() -> {
new MathQuizWithTimer().setVisible(true);
});
}
}

浙公网安备 33010602011771号