You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MathLearningSoftware/src/com/mathlearning/view/QuizFrame.java

283 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.mathlearning.view;
import com.mathlearning.controller.QuestionController;
import com.mathlearning.model.Question;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class QuizFrame extends JFrame {
private QuestionController questionController;
private String level;
private int totalQuestions;
private LevelSelectionFrame parentFrame;
private JLabel questionNumberLabel;
private JLabel questionTextLabel;
private JRadioButton[] optionButtons;
private ButtonGroup buttonGroup;
private JButton previousButton;
private JButton nextButton;
private JProgressBar progressBar;
// 存储所有题目和用户选择
private List<Question> allQuestions;
private int[] userSelections;
private int currentDisplayIndex; // 当前显示的题目索引
public QuizFrame(String level, int questionCount, LevelSelectionFrame parent) {
this.parentFrame = parent;
this.level = level;
this.totalQuestions = questionCount;
this.questionController = new QuestionController();
this.questionController.startNewQuiz(level, questionCount);
// 获取所有题目
this.allQuestions = questionController.getCurrentQuestions();
this.userSelections = new int[questionCount];
this.currentDisplayIndex = 0;
// 初始化选择为-1未选择
for (int i = 0; i < userSelections.length; i++) {
userSelections[i] = -1;
}
initializeUI();
showCurrentQuestion();
}
private void initializeUI() {
setTitle("数学答题 - " + level);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(700, 550);
setLocationRelativeTo(null);
setResizable(false);
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 顶部面板(退出按钮和进度条)
JPanel topPanel = new JPanel(new BorderLayout());
JButton exitButton = new JButton("退出答题");
exitButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
exitButton.setBackground(new Color(220, 100, 100));
exitButton.setForeground(Color.WHITE);
exitButton.addActionListener(e -> exitQuiz());
progressBar = new JProgressBar(0, totalQuestions);
progressBar.setValue(0);
progressBar.setStringPainted(true);
progressBar.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
topPanel.add(exitButton, BorderLayout.WEST);
topPanel.add(progressBar, BorderLayout.CENTER);
mainPanel.add(topPanel, BorderLayout.NORTH);
// 问题面板
JPanel questionPanel = new JPanel(new BorderLayout(10, 20));
questionPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
questionNumberLabel = new JLabel("", JLabel.CENTER);
questionNumberLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
questionNumberLabel.setForeground(new Color(0, 100, 200));
questionPanel.add(questionNumberLabel, BorderLayout.NORTH);
questionTextLabel = new JLabel("", JLabel.CENTER);
questionTextLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
questionTextLabel.setBorder(BorderFactory.createEmptyBorder(20, 10, 20, 10));
questionPanel.add(questionTextLabel, BorderLayout.CENTER);
mainPanel.add(questionPanel, BorderLayout.CENTER);
// 选项面板
JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 10, 10));
optionsPanel.setBorder(
BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY), "请选择答案"));
optionButtons = new JRadioButton[4];
buttonGroup = new ButtonGroup();
for (int i = 0; i < 4; i++) {
optionButtons[i] = new JRadioButton();
optionButtons[i].setFont(new Font("Microsoft YaHei", Font.PLAIN, 16));
optionButtons[i].setBackground(Color.WHITE);
optionButtons[i].setFocusPainted(false);
optionButtons[i].setPreferredSize(new Dimension(400, 40));
final int index = i;
optionButtons[i].addActionListener(
e -> {
// 保存当前选择
userSelections[currentDisplayIndex] = index;
System.out.println("用户选择: 第" + (currentDisplayIndex + 1) + "题 -> 选项" + index);
});
buttonGroup.add(optionButtons[i]);
optionsPanel.add(optionButtons[i]);
}
JPanel optionsContainer = new JPanel(new FlowLayout(FlowLayout.CENTER));
optionsContainer.add(optionsPanel);
// 控制面板
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
previousButton = new JButton("上一题");
previousButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
previousButton.setBackground(new Color(169, 169, 169));
previousButton.setForeground(Color.WHITE);
previousButton.setFocusPainted(false);
previousButton.setBorder(BorderFactory.createEmptyBorder(8, 20, 8, 20));
previousButton.setEnabled(false); // 第一题时禁用
nextButton = new JButton("下一题");
nextButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
nextButton.setBackground(new Color(70, 130, 180));
nextButton.setForeground(Color.WHITE);
nextButton.setFocusPainted(false);
nextButton.setBorder(BorderFactory.createEmptyBorder(10, 30, 10, 30));
controlPanel.add(previousButton);
controlPanel.add(nextButton);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.add(optionsContainer, BorderLayout.CENTER);
southPanel.add(controlPanel, BorderLayout.SOUTH);
mainPanel.add(southPanel, BorderLayout.SOUTH);
// 添加事件监听器
previousButton.addActionListener(new PreviousQuestionAction());
nextButton.addActionListener(new NextQuestionAction());
add(mainPanel);
}
private void showCurrentQuestion() {
if (currentDisplayIndex >= allQuestions.size()) {
finishQuiz();
return;
}
Question currentQuestion = allQuestions.get(currentDisplayIndex);
questionNumberLabel.setText(
String.format("第 %d 题 / 共 %d 题", currentDisplayIndex + 1, totalQuestions));
questionTextLabel.setText(
"<html><div style='text-align: center;'>"
+ currentQuestion.getQuestionText()
+ "</div></html>");
String[] options = currentQuestion.getOptions();
for (int i = 0; i < 4; i++) {
String optionText =
String.format(
"<html><div style='padding: 5px;'>%c. %s</div></html>", (char) ('A' + i), options[i]);
optionButtons[i].setText(optionText);
}
buttonGroup.clearSelection(); // 清除当前选择状态
// 恢复之前的选择(如果有)
if (userSelections[currentDisplayIndex] != -1) {
int previousSelection = userSelections[currentDisplayIndex];
if (previousSelection >= 0 && previousSelection < 4) {
optionButtons[previousSelection].setSelected(true);
}
}
// 更新进度条
progressBar.setValue(currentDisplayIndex);
progressBar.setString(
String.format(
"%d/%d (%.0f%%)",
currentDisplayIndex,
totalQuestions,
((double) currentDisplayIndex / totalQuestions) * 100));
updateButtonStates(); // 更新按钮状态
}
private void exitQuiz() {
int result =
JOptionPane.showConfirmDialog(this, "确定要退出答题吗?所有进度将丢失。", "退出确认", JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
parentFrame.setVisible(true);
this.dispose();
}
}
private void updateButtonStates() {
// 更新上一题按钮状态
previousButton.setEnabled(currentDisplayIndex > 0);
// 更新下一题按钮文本
if (currentDisplayIndex == totalQuestions - 1) {
nextButton.setText("完成答题");
} else {
nextButton.setText("下一题");
}
}
private class PreviousQuestionAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (currentDisplayIndex > 0) {
currentDisplayIndex--;
showCurrentQuestion();
}
}
}
private class NextQuestionAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// 检查是否选择了答案
int selectedIndex = -1;
for (int i = 0; i < 4; i++) {
if (optionButtons[i].isSelected()) {
selectedIndex = i;
break;
}
}
userSelections[currentDisplayIndex] = selectedIndex; // 保存当前选择
// 如果没有选择答案,提示用户但允许继续(除了最后一题)
if (selectedIndex == -1) {
int result =
JOptionPane.showConfirmDialog(
QuizFrame.this, "您还没有选择答案,确定要继续下一题吗?", "确认", JOptionPane.YES_NO_OPTION);
if (result != JOptionPane.YES_OPTION) {
return;
}
}
// 前进到下一题或完成
if (currentDisplayIndex < totalQuestions - 1) {
currentDisplayIndex++;
showCurrentQuestion();
} else {
submitAllAnswers(); // 完成所有题目,提交答案并显示分数
finishQuiz();
}
}
}
private void submitAllAnswers() {
// 计算分数
int score = 0;
for (int i = 0; i < totalQuestions; i++) {
if (userSelections[i] != -1) {
// 使用 QuestionController 来检查答案
questionController.setCurrentQuestionIndex(i);
if (questionController.submitAnswer(userSelections[i])) {
score++;
}
}
}
// 重置到第一个问题,以便在结果显示时能正确访问
questionController.setCurrentQuestionIndex(0);
}
private void finishQuiz() {
// 使用原有的构造函数
ScoreFrame scoreFrame =
new ScoreFrame(questionController, userSelections, allQuestions, parentFrame);
scoreFrame.setVisible(true);
this.dispose();
}
} // 添加这个闭合大括号