package com.example.mathsystemtogether; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.animation.Timeline; import javafx.animation.KeyFrame; import javafx.util.Duration; import java.util.*; /** * 考试进行界面控制器 */ public class ExamTakingController { // 界面控件 @FXML private Label examInfoLabel; @FXML private Label questionNumberLabel; @FXML private Label timeLabel; @FXML private Label questionTextLabel; @FXML private RadioButton optionA; @FXML private RadioButton optionB; @FXML private RadioButton optionC; @FXML private RadioButton optionD; @FXML private ToggleGroup answerGroup; @FXML private Button submitButton; @FXML private Button nextButton; @FXML private Button exitExamButton; @FXML private ProgressBar progressBar; @FXML private Label progressLabel; // 数据成员 private List examQuestions; private int currentQuestionIndex = 0; private Map userAnswers = new HashMap<>(); private ChoiceQuestionGenerator questionGenerator; private String username; private String level; private int totalQuestions; private Timeline timer; private int remainingSeconds; @FXML public void initialize() { setupAnswerGroup(); setupTimer(); } private void setupAnswerGroup() { answerGroup = new ToggleGroup(); optionA.setToggleGroup(answerGroup); optionB.setToggleGroup(answerGroup); optionC.setToggleGroup(answerGroup); optionD.setToggleGroup(answerGroup); } private void setupTimer() { // 设置30分钟倒计时 remainingSeconds = 30 * 60; // 30分钟 = 1800秒 timer = new Timeline(new KeyFrame(Duration.seconds(1), e -> updateTimer())); timer.setCycleCount(Timeline.INDEFINITE); timer.play(); } private void updateTimer() { remainingSeconds--; if (remainingSeconds <= 0) { timer.stop(); handleTimeUp(); return; } int minutes = remainingSeconds / 60; int seconds = remainingSeconds % 60; timeLabel.setText(String.format("⏰ 剩余时间: %02d:%02d", minutes, seconds)); } private void handleTimeUp() { Alert alert = new Alert(Alert.AlertType.WARNING); alert.setTitle("时间到"); alert.setHeaderText("考试时间已到!"); alert.setContentText("系统将自动提交您的答案。"); alert.showAndWait(); showResults(); } public void setExamData(List questions, String username, String level) { this.examQuestions = questions; this.username = username; this.level = level; this.totalQuestions = questions.size(); examInfoLabel.setText(String.format("👤 %s | 📚 %s | 📝 %d题", username, level, totalQuestions)); displayCurrentQuestion(); updateProgress(); } private void displayCurrentQuestion() { if (currentQuestionIndex >= examQuestions.size()) { showResults(); return; } Question question = examQuestions.get(currentQuestionIndex); questionNumberLabel.setText(String.format("第 %d 题 / 共 %d 题", currentQuestionIndex + 1, examQuestions.size())); questionTextLabel.setText(question.getQuestionText()); optionA.setText("A. " + question.getOptionA()); optionB.setText("B. " + question.getOptionB()); optionC.setText("C. " + question.getOptionC()); optionD.setText("D. " + question.getOptionD()); // 清除之前的选择 answerGroup.selectToggle(null); // 更新按钮状态 if (currentQuestionIndex == examQuestions.size() - 1) { submitButton.setText("✅ 提交并完成考试"); nextButton.setVisible(false); } else { submitButton.setText("✅ 提交答案"); nextButton.setVisible(true); } updateProgress(); } private void updateProgress() { double progress = (double) currentQuestionIndex / examQuestions.size(); progressBar.setProgress(progress); progressLabel.setText(String.format("进度: %d/%d (%.1f%%)", currentQuestionIndex + 1, examQuestions.size(), progress * 100)); } @FXML private void handleSubmitAnswer() { RadioButton selectedOption = (RadioButton) answerGroup.getSelectedToggle(); if (selectedOption == null) { showAlert("请选择一个答案", "请先选择答案再提交"); return; } String answer = getAnswerValue(selectedOption.getText().substring(0, 1)); // 获取答案 userAnswers.put(currentQuestionIndex, answer); if (currentQuestionIndex == examQuestions.size() - 1) { // 最后一题,显示结果 timer.stop(); showResults(); } else { // 下一题 currentQuestionIndex++; displayCurrentQuestion(); } } // 添加辅助方法获取选项对应的实际值 private String getAnswerValue(String optionLetter) { Question currentQuestion = examQuestions.get(currentQuestionIndex); switch (optionLetter) { case "A": return currentQuestion.getOptionA(); case "B": return currentQuestion.getOptionB(); case "C": return currentQuestion.getOptionC(); case "D": return currentQuestion.getOptionD(); default: return ""; } } @FXML private void handleNextQuestion() { currentQuestionIndex++; displayCurrentQuestion(); } @FXML private void handleExitExam() { if (showExitConfirmation()) { timer.stop(); returnToMainMenu(); } } private boolean showExitConfirmation() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle("确认退出"); alert.setHeaderText("确定要退出考试吗?"); alert.setContentText("退出后当前进度将丢失。"); return alert.showAndWait().orElse(ButtonType.CANCEL) == ButtonType.OK; } private void showAlert(String title, String message) { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle(title); alert.setHeaderText(null); alert.setContentText(message); alert.showAndWait(); } private void showResults() { try { // 停止计时器 timer.stop(); // 计算成绩 int correctCount = 0; StringBuilder resultDetails = new StringBuilder(); for (int i = 0; i < examQuestions.size(); i++) { Question question = examQuestions.get(i); String userAnswer = userAnswers.get(i); boolean isCorrect = question.isCorrect(userAnswer); if (isCorrect) { correctCount++; } resultDetails.append("第").append(i + 1).append("题: "); resultDetails.append(question.getQuestionText()).append("\n"); resultDetails.append("你的答案: ").append(userAnswer != null ? userAnswer : "未作答").append(" "); resultDetails.append("正确答案: ").append(question.getCorrectAnswer()).append(" "); resultDetails.append(isCorrect ? "✓" : "✗").append("\n\n"); } int score = (int) Math.round((double) correctCount / examQuestions.size() * 100); // 显示结果对话框 Alert resultAlert = new Alert(Alert.AlertType.INFORMATION); resultAlert.setTitle("考试完成"); resultAlert.setHeaderText("🎉 考试结果"); resultAlert.setContentText(String.format( "得分: %d分\n正确: %d题\n总计: %d题\n正确率: %.1f%%", score, correctCount, examQuestions.size(), (double) correctCount / examQuestions.size() * 100 )); resultAlert.showAndWait(); // 返回主菜单 returnToMainMenu(); } catch (Exception e) { showAlert("错误", "显示结果时出错:" + e.getMessage()); } } private void returnToMainMenu() { try { // 关闭当前窗口 Stage currentStage = (Stage) submitButton.getScene().getWindow(); currentStage.close(); // 打开主菜单 FXMLLoader loader = new FXMLLoader(getClass().getResource("exam-view.fxml")); Scene scene = new Scene(loader.load(), 1000, 900); Stage stage = new Stage(); stage.setTitle("数学考试系统"); stage.setScene(scene); stage.show(); } catch (Exception e) { showAlert("错误", "返回主菜单时出错:" + e.getMessage()); } } }