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.
197 lines
5.8 KiB
197 lines
5.8 KiB
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<Question> 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("<html><body style='width: 500px'>" +
|
|
question.getQuestionText() + "</body></html>");
|
|
|
|
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();
|
|
}
|
|
} |