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 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( "
" + currentQuestion.getQuestionText() + "
"); String[] options = currentQuestion.getOptions(); for (int i = 0; i < 4; i++) { String optionText = String.format( "
%c. %s
", (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(); } } // 添加这个闭合大括号