package ui; import model.Grade; import model.Question; import model.QuestionMaker; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.Serial; import java.util.List; /** * 答题界面 * 显示题目和选项,接收用户答案 */ public class QuizFrame extends JFrame { @Serial private static final long serialVersionUID = 1L; private final String email; private final Grade gradeType; private final List questions; private int currentIndex; private int correctCount; private JLabel questionLabel; private JLabel progressLabel; private JRadioButton[] optionButtons; private JButton submitButton; /** * 构造答题界面 * * @param email 用户邮箱 * @param gradeType 年级类型 * @param questionCount 题目数量 */ public QuizFrame(String email, Grade gradeType, int questionCount) { this.email = email; this.gradeType = gradeType; this.currentIndex = 0; this.correctCount = 0; QuestionMaker generator = new QuestionMaker(); this.questions = generator.makeQuestions(gradeType, questionCount, email); if (questions.isEmpty()) { JOptionPane.showMessageDialog(null, "生成题目失败,返回主界面", "错误", JOptionPane.ERROR_MESSAGE); returnToGradeSelection(); return; } setTitle("数学学习软件 - 答题"); setSize(600, 450); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setResizable(false); JPanel mainPanel = new JPanel(new BorderLayout(10, 10)); mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); progressLabel = new JLabel("", JLabel.CENTER); progressLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); mainPanel.add(progressLabel, BorderLayout.NORTH); JPanel centerPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(10, 10, 10, 10); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2; questionLabel = new JLabel(); questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16)); questionLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10)); centerPanel.add(questionLabel, gbc); ButtonGroup optionGroup = new ButtonGroup(); optionButtons = new JRadioButton[4]; for (int i = 0; i < 4; i++) { optionButtons[i] = new JRadioButton(); optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 14)); optionGroup.add(optionButtons[i]); gbc.gridy = i + 1; centerPanel.add(optionButtons[i], gbc); } mainPanel.add(centerPanel, BorderLayout.CENTER); JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); submitButton = new JButton("提交答案"); submitButton.setPreferredSize(new Dimension(150, 35)); submitButton.setFont(new Font("微软雅黑", Font.BOLD, 14)); bottomPanel.add(submitButton); mainPanel.add(bottomPanel, BorderLayout.SOUTH); add(mainPanel); submitButton.addActionListener(e -> handleSubmit()); displayQuestion(); } /** * 显示当前题目 */ private void displayQuestion() { if (currentIndex >= questions.size()) { showResult(); return; } Question question = questions.get(currentIndex); progressLabel.setText(String.format("第 %d/%d 题", currentIndex + 1, questions.size())); questionLabel.setText("" + question.getQuestionText() + ""); String[] options = question.getOptions(); for (int i = 0; i < 4; i++) { optionButtons[i].setText(options[i]); optionButtons[i].setSelected(false); } submitButton.setEnabled(true); } /** * 处理答案提交 */ private void handleSubmit() { int selectedIndex = -1; for (int i = 0; i < 4; i++) { if (optionButtons[i].isSelected()) { selectedIndex = i; break; } } if (selectedIndex == -1) { JOptionPane.showMessageDialog(this, "请选择一个答案", "提示", JOptionPane.WARNING_MESSAGE); return; } Question question = questions.get(currentIndex); if (selectedIndex == question.getCorrectAnswer()) { correctCount++; } currentIndex++; displayQuestion(); } /** * 显示答题结果 */ private void showResult() { double percentage = (double) correctCount / questions.size() * 100; int score = (int) percentage; ResultFrame resultFrame = new ResultFrame( email, gradeType, score, correctCount, questions.size()); resultFrame.setVisible(true); this.dispose(); } /** * 返回年级选择界面 */ private void returnToGradeSelection() { GradeSelectionFrame frame = new GradeSelectionFrame(email, gradeType); frame.setVisible(true); this.dispose(); } }