main
commit
9ef97d3661
@ -0,0 +1,164 @@
|
||||
package com.example.mathsystemtogether;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ChangePasswordController {
|
||||
|
||||
@FXML
|
||||
private TextField usernameField;
|
||||
|
||||
@FXML
|
||||
private PasswordField oldPasswordField;
|
||||
|
||||
@FXML
|
||||
private PasswordField newPasswordField;
|
||||
|
||||
@FXML
|
||||
private PasswordField confirmNewPasswordField;
|
||||
|
||||
@FXML
|
||||
private Button changePasswordButton;
|
||||
|
||||
@FXML
|
||||
private Button cancelButton;
|
||||
|
||||
@FXML
|
||||
private Label statusLabel;
|
||||
|
||||
private String currentUser;
|
||||
private ExamController examController;
|
||||
private static final String USER_DATA_FILE = "user_data.txt";
|
||||
|
||||
// 密码强度验证正则表达式
|
||||
private static final String PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).+$";
|
||||
private static final Pattern PASSWORD_PATTERN = Pattern.compile(PASSWORD_REGEX);
|
||||
|
||||
public void setCurrentUser(String username) {
|
||||
this.currentUser = username;
|
||||
usernameField.setText(username);
|
||||
}
|
||||
|
||||
public void setExamController(ExamController examController) {
|
||||
this.examController = examController;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleChangePassword() {
|
||||
String oldPassword = oldPasswordField.getText();
|
||||
String newPassword = newPasswordField.getText();
|
||||
String confirmNewPassword = confirmNewPasswordField.getText();
|
||||
|
||||
if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmNewPassword.isEmpty()) {
|
||||
showStatus("请填写所有字段", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!examController.checkUserPassword(currentUser, oldPassword)) {
|
||||
showStatus("原密码错误", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword.length() < 6) {
|
||||
showStatus("新密码至少需要6个字符", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isValidPassword(newPassword)) {
|
||||
showStatus("新密码必须包含大小写字母和数字", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newPassword.equals(confirmNewPassword)) {
|
||||
showStatus("两次输入的新密码不一致", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldPassword.equals(newPassword)) {
|
||||
showStatus("新密码不能与原密码相同", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (updatePassword(currentUser, newPassword)) {
|
||||
showStatus("密码修改成功!", false);
|
||||
|
||||
// 延迟关闭窗口
|
||||
new java.util.Timer().schedule(
|
||||
new java.util.TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
javafx.application.Platform.runLater(() -> {
|
||||
handleClose();
|
||||
});
|
||||
}
|
||||
},
|
||||
1500
|
||||
);
|
||||
} else {
|
||||
showStatus("密码修改失败,请重试", true);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleCancel() {
|
||||
handleClose();
|
||||
}
|
||||
|
||||
private void handleClose() {
|
||||
Stage stage = (Stage) cancelButton.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
private boolean updatePassword(String username, String newPassword) {
|
||||
try {
|
||||
// 读取所有用户数据
|
||||
List<String> lines = Files.readAllLines(Paths.get(USER_DATA_FILE));
|
||||
boolean userFound = false;
|
||||
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
String[] parts = lines.get(i).split("\\|");
|
||||
if (parts.length >= 2 && parts[0].equals(username)) {
|
||||
// 更新密码
|
||||
parts[1] = newPassword;
|
||||
lines.set(i, String.join("|", parts));
|
||||
userFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (userFound) {
|
||||
// 写回文件
|
||||
Files.write(Paths.get(USER_DATA_FILE), lines);
|
||||
// 更新内存中的用户数据
|
||||
examController.updateUserPassword(username, newPassword);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证密码强度
|
||||
* 密码必须包含至少一个小写字母、一个大写字母和一个数字
|
||||
*/
|
||||
private boolean isValidPassword(String password) {
|
||||
return PASSWORD_PATTERN.matcher(password).matches();
|
||||
}
|
||||
|
||||
private void showStatus(String message, boolean isError) {
|
||||
statusLabel.setText(message);
|
||||
if (isError) {
|
||||
statusLabel.setStyle("-fx-text-fill: #DC143C; -fx-font-weight: bold; -fx-font-size: 14;");
|
||||
} else {
|
||||
statusLabel.setStyle("-fx-text-fill: #228B22; -fx-font-weight: bold; -fx-font-size: 14;");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,175 @@
|
||||
package com.example.mathsystemtogether;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.FontWeight;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考试详细信息界面控制器
|
||||
*/
|
||||
public class ExamDetailsController {
|
||||
|
||||
@FXML private Label examInfoLabel;
|
||||
@FXML private ScrollPane detailsScrollPane;
|
||||
@FXML private VBox detailsContainer;
|
||||
@FXML private Button scrollToTopButton;
|
||||
@FXML private Button scrollToBottomButton;
|
||||
@FXML private Button closeButton;
|
||||
|
||||
// 数据成员
|
||||
private List<Question> examQuestions;
|
||||
private List<String> userAnswers;
|
||||
private String username;
|
||||
private String level;
|
||||
|
||||
/**
|
||||
* 设置考试详细信息
|
||||
*/
|
||||
public void setExamDetails(List<Question> questions, List<String> answers, String username, String level) {
|
||||
this.examQuestions = questions;
|
||||
this.userAnswers = answers;
|
||||
this.username = username;
|
||||
this.level = level;
|
||||
|
||||
// 更新界面显示
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新界面显示
|
||||
*/
|
||||
private void updateDisplay() {
|
||||
// 更新考试信息
|
||||
examInfoLabel.setText(String.format("用户: %s | 级别: %s | 题目: %d题", username, level, examQuestions.size()));
|
||||
|
||||
// 清空容器
|
||||
detailsContainer.getChildren().clear();
|
||||
|
||||
// 添加每道题的详细信息
|
||||
for (int i = 0; i < examQuestions.size(); i++) {
|
||||
Question question = examQuestions.get(i);
|
||||
String userAnswer = i < userAnswers.size() ? userAnswers.get(i) : "未作答";
|
||||
boolean isCorrect = question.isCorrect(userAnswer);
|
||||
|
||||
// 创建题目详情卡片
|
||||
VBox questionCard = createQuestionCard(i + 1, question, userAnswer, isCorrect);
|
||||
detailsContainer.getChildren().add(questionCard);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建题目详情卡片
|
||||
*/
|
||||
private VBox createQuestionCard(int questionNumber, Question question, String userAnswer, boolean isCorrect) {
|
||||
VBox card = new VBox();
|
||||
card.setSpacing(10);
|
||||
card.setStyle("-fx-background-color: " + (isCorrect ? "rgba(144,238,144,0.3)" : "rgba(255,182,193,0.3)") +
|
||||
"; -fx-background-radius: 10; -fx-padding: 15; -fx-border-color: " +
|
||||
(isCorrect ? "#90EE90" : "#FFB6C1") + "; -fx-border-radius: 10; -fx-border-width: 2;");
|
||||
|
||||
// 题目编号和状态
|
||||
HBox headerBox = new HBox();
|
||||
headerBox.setSpacing(10);
|
||||
|
||||
Label questionNumLabel = new Label("第 " + questionNumber + " 题");
|
||||
questionNumLabel.setFont(Font.font("System", FontWeight.BOLD, 16));
|
||||
questionNumLabel.setTextFill(Color.DARKBLUE);
|
||||
|
||||
Label statusLabel = new Label(isCorrect ? "✓ 正确" : "✗ 错误");
|
||||
statusLabel.setFont(Font.font("System", FontWeight.BOLD, 14));
|
||||
statusLabel.setTextFill(isCorrect ? Color.GREEN : Color.RED);
|
||||
|
||||
headerBox.getChildren().addAll(questionNumLabel, statusLabel);
|
||||
|
||||
// 题目内容
|
||||
Label questionLabel = new Label("题目: " + question.getQuestionText());
|
||||
questionLabel.setFont(Font.font("System", 14));
|
||||
questionLabel.setWrapText(true);
|
||||
|
||||
// 选项
|
||||
VBox optionsBox = new VBox();
|
||||
optionsBox.setSpacing(5);
|
||||
|
||||
Label optionALabel = new Label("A. " + question.getOptionA());
|
||||
Label optionBLabel = new Label("B. " + question.getOptionB());
|
||||
Label optionCLabel = new Label("C. " + question.getOptionC());
|
||||
Label optionDLabel = new Label("D. " + question.getOptionD());
|
||||
|
||||
// 高亮用户答案和正确答案
|
||||
highlightAnswer(optionALabel, question.getOptionA(), userAnswer, question.getCorrectAnswer());
|
||||
highlightAnswer(optionBLabel, question.getOptionB(), userAnswer, question.getCorrectAnswer());
|
||||
highlightAnswer(optionCLabel, question.getOptionC(), userAnswer, question.getCorrectAnswer());
|
||||
highlightAnswer(optionDLabel, question.getOptionD(), userAnswer, question.getCorrectAnswer());
|
||||
|
||||
optionsBox.getChildren().addAll(optionALabel, optionBLabel, optionCLabel, optionDLabel);
|
||||
|
||||
// 答案信息
|
||||
HBox answerBox = new HBox();
|
||||
answerBox.setSpacing(20);
|
||||
|
||||
Label userAnswerLabel = new Label("你的答案: " + userAnswer);
|
||||
userAnswerLabel.setFont(Font.font("System", FontWeight.BOLD, 12));
|
||||
userAnswerLabel.setTextFill(Color.BLUE);
|
||||
|
||||
Label correctAnswerLabel = new Label("正确答案: " + question.getCorrectAnswer());
|
||||
correctAnswerLabel.setFont(Font.font("System", FontWeight.BOLD, 12));
|
||||
correctAnswerLabel.setTextFill(Color.GREEN);
|
||||
|
||||
answerBox.getChildren().addAll(userAnswerLabel, correctAnswerLabel);
|
||||
|
||||
// 添加到卡片
|
||||
card.getChildren().addAll(headerBox, questionLabel, optionsBox, answerBox);
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
/**
|
||||
* 高亮显示答案选项
|
||||
*/
|
||||
private void highlightAnswer(Label optionLabel, String optionValue, String userAnswer, String correctAnswer) {
|
||||
optionLabel.setFont(Font.font("System", 12));
|
||||
|
||||
if (optionValue.equals(correctAnswer)) {
|
||||
// 正确答案 - 绿色背景
|
||||
optionLabel.setStyle("-fx-background-color: rgba(144,238,144,0.5); -fx-background-radius: 5; -fx-padding: 5; -fx-font-weight: bold;");
|
||||
} else if (optionValue.equals(userAnswer) && !userAnswer.equals(correctAnswer)) {
|
||||
// 用户错误答案 - 红色背景
|
||||
optionLabel.setStyle("-fx-background-color: rgba(255,182,193,0.5); -fx-background-radius: 5; -fx-padding: 5; -fx-font-weight: bold;");
|
||||
} else {
|
||||
// 其他选项 - 默认样式
|
||||
optionLabel.setStyle("-fx-padding: 5;");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理滚动到顶部按钮
|
||||
*/
|
||||
@FXML
|
||||
private void handleScrollToTop() {
|
||||
detailsScrollPane.setVvalue(0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理滚动到底部按钮
|
||||
*/
|
||||
@FXML
|
||||
private void handleScrollToBottom() {
|
||||
detailsScrollPane.setVvalue(1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理关闭按钮
|
||||
*/
|
||||
@FXML
|
||||
private void handleClose() {
|
||||
Stage stage = (Stage) closeButton.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,206 @@
|
||||
package com.example.mathsystemtogether;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考试结果界面控制器
|
||||
*/
|
||||
public class ExamResultController {
|
||||
|
||||
@FXML private Label titleLabel;
|
||||
@FXML private Label subtitleLabel;
|
||||
@FXML private Label scoreLabel;
|
||||
@FXML private Label correctCountLabel;
|
||||
@FXML private Label totalCountLabel;
|
||||
@FXML private Label accuracyLabel;
|
||||
@FXML private Label gradeLabel;
|
||||
@FXML private Label commentLabel;
|
||||
@FXML private Button continueButton;
|
||||
@FXML private Button exitButton;
|
||||
@FXML private Button detailsButton;
|
||||
|
||||
// 数据成员
|
||||
private List<Question> examQuestions;
|
||||
private List<String> userAnswers;
|
||||
private String username;
|
||||
private String level;
|
||||
private int score;
|
||||
private int correctCount;
|
||||
private int totalCount;
|
||||
private double accuracy;
|
||||
|
||||
/**
|
||||
* 设置考试结果数据
|
||||
*/
|
||||
public void setExamResult(List<Question> questions, List<String> answers, String username, String level) {
|
||||
this.examQuestions = questions;
|
||||
this.userAnswers = answers;
|
||||
this.username = username;
|
||||
this.level = level;
|
||||
this.totalCount = questions.size();
|
||||
|
||||
// 计算成绩
|
||||
calculateScore();
|
||||
|
||||
// 更新界面显示
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算考试成绩
|
||||
*/
|
||||
private void calculateScore() {
|
||||
correctCount = 0;
|
||||
|
||||
for (int i = 0; i < examQuestions.size(); i++) {
|
||||
Question question = examQuestions.get(i);
|
||||
String userAnswer = i < userAnswers.size() ? userAnswers.get(i) : "";
|
||||
|
||||
if (question.isCorrect(userAnswer)) {
|
||||
correctCount++;
|
||||
}
|
||||
}
|
||||
|
||||
score = (int) Math.round((double) correctCount / totalCount * 100);
|
||||
accuracy = (double) correctCount / totalCount * 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新界面显示
|
||||
*/
|
||||
private void updateDisplay() {
|
||||
// 更新分数显示
|
||||
scoreLabel.setText(String.format("得分: %d分", score));
|
||||
correctCountLabel.setText(String.format("正确: %d题", correctCount));
|
||||
totalCountLabel.setText(String.format("总计: %d题", totalCount));
|
||||
accuracyLabel.setText(String.format("正确率: %.1f%%", accuracy));
|
||||
|
||||
// 更新成绩评价
|
||||
String grade = getGrade(score);
|
||||
String comment = getComment(score);
|
||||
|
||||
gradeLabel.setText(grade);
|
||||
commentLabel.setText(comment);
|
||||
|
||||
// 根据成绩调整颜色
|
||||
updateGradeColor(score);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成绩等级
|
||||
*/
|
||||
private String getGrade(int score) {
|
||||
if (score >= 90) return "优秀";
|
||||
else if (score >= 80) return "良好";
|
||||
else if (score >= 70) return "中等";
|
||||
else if (score >= 60) return "及格";
|
||||
else return "不及格";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成绩评语
|
||||
*/
|
||||
private String getComment(int score) {
|
||||
if (score >= 90) return "表现非常出色!继续保持!";
|
||||
else if (score >= 80) return "表现良好,还有提升空间!";
|
||||
else if (score >= 70) return "表现中等,需要加强练习!";
|
||||
else if (score >= 60) return "刚刚及格,需要更多努力!";
|
||||
else return "需要认真学习,多加练习!";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据成绩更新颜色
|
||||
*/
|
||||
private void updateGradeColor(int score) {
|
||||
String color;
|
||||
if (score >= 90) color = "#2E8B57"; // 绿色
|
||||
else if (score >= 80) color = "#32CD32"; // 浅绿色
|
||||
else if (score >= 70) color = "#FFD700"; // 金色
|
||||
else if (score >= 60) color = "#FF8C00"; // 橙色
|
||||
else color = "#DC143C"; // 红色
|
||||
|
||||
gradeLabel.setStyle("-fx-font-size: 24; -fx-font-weight: bold; -fx-text-fill: " + color + ";");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理继续做题按钮
|
||||
*/
|
||||
@FXML
|
||||
private void handleContinueExam() {
|
||||
try {
|
||||
// 关闭当前窗口
|
||||
Stage currentStage = (Stage) continueButton.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);
|
||||
|
||||
// 获取主界面控制器并设置用户信息
|
||||
ExamController examController = loader.getController();
|
||||
examController.setUserForContinueExam(username, level);
|
||||
|
||||
stage.show();
|
||||
|
||||
} catch (Exception e) {
|
||||
showAlert("错误", "打开考试设置界面时出错:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理退出系统按钮
|
||||
*/
|
||||
@FXML
|
||||
private void handleExitSystem() {
|
||||
// 关闭当前窗口
|
||||
Stage currentStage = (Stage) exitButton.getScene().getWindow();
|
||||
currentStage.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理查看详细信息按钮
|
||||
*/
|
||||
@FXML
|
||||
private void handleShowDetails() {
|
||||
try {
|
||||
// 打开详细信息窗口
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("exam-details-view.fxml"));
|
||||
Scene scene = new Scene(loader.load(), 300, 700);
|
||||
Stage detailsStage = new Stage();
|
||||
detailsStage.setTitle("详细答题情况");
|
||||
detailsStage.setScene(scene);
|
||||
detailsStage.setResizable(true);
|
||||
detailsStage.setMinWidth(800);
|
||||
detailsStage.setMinHeight(600);
|
||||
|
||||
// 传递数据给详细信息控制器
|
||||
ExamDetailsController controller = loader.getController();
|
||||
controller.setExamDetails(examQuestions, userAnswers, username, level);
|
||||
|
||||
detailsStage.show();
|
||||
|
||||
} catch (Exception e) {
|
||||
showAlert("错误", "打开详细信息时出错:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示警告对话框
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.effect.DropShadow?>
|
||||
|
||||
<VBox xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.mathsystemtogether.ChangePasswordController"
|
||||
spacing="20.0" style="-fx-background-color: linear-gradient(to bottom, #6A0DAD, #4B0082, #2E0854);"
|
||||
prefHeight="500.0" prefWidth="600.0">
|
||||
<padding>
|
||||
<Insets bottom="30.0" left="40.0" right="40.0" top="30.0"/>
|
||||
</padding>
|
||||
|
||||
<VBox spacing="15.0" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC, #8B008B); -fx-background-radius: 15; -fx-padding: 20;">
|
||||
<Label text="🔐 修改密码" textFill="white" textAlignment="CENTER" style="-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.5), 10, 0, 0, 2);">
|
||||
<font>
|
||||
<Font name="System Bold" size="24.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</VBox>
|
||||
|
||||
<VBox spacing="20.0" style="-fx-background-color: linear-gradient(to bottom, #E6E6FA, #D8BFD8, #DDA0DD); -fx-padding: 25; -fx-background-radius: 15; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.3), 15, 0, 0, 5);">
|
||||
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="👤 用户名:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<TextField fx:id="usernameField" editable="false" prefWidth="250.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="🔑 原密码:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<PasswordField fx:id="oldPasswordField" prefWidth="250.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="🆕 新密码:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<PasswordField fx:id="newPasswordField" prefWidth="250.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="✅ 确认密码:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<PasswordField fx:id="confirmNewPasswordField" prefWidth="250.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="20.0" alignment="CENTER">
|
||||
<Button fx:id="changePasswordButton" text="💾 保存修改" onAction="#handleChangePassword" style="-fx-background-color: linear-gradient(to right, #32CD32, #228B22); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 12 25; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
<Button fx:id="cancelButton" text="❌ 取消" onAction="#handleCancel" style="-fx-background-color: linear-gradient(to right, #DC143C, #B22222); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 12 25; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
</HBox>
|
||||
|
||||
<Label fx:id="statusLabel" textFill="#8B0000" style="-fx-font-weight: bold; -fx-font-size: 14;" textAlignment="CENTER"/>
|
||||
</VBox>
|
||||
|
||||
</VBox>
|
||||
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.mathsystemtogether.ExamDetailsController">
|
||||
<children>
|
||||
<!-- 背景渐变 -->
|
||||
<AnchorPane style="-fx-background-color: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
||||
<children>
|
||||
<!-- 主要内容区域 -->
|
||||
<VBox alignment="CENTER" spacing="20.0" style="-fx-background-color: rgba(255,255,255,0.95); -fx-background-radius: 20; -fx-padding: 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 20, 0, 0, 5);" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="30.0">
|
||||
<children>
|
||||
<!-- 标题区域 -->
|
||||
<VBox alignment="CENTER" spacing="10.0">
|
||||
<Label text="📊 详细答题情况" style="-fx-font-size: 28; -fx-font-weight: bold; -fx-text-fill: #2E8B57; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
<Label fx:id="examInfoLabel" text="用户: 张三 | 级别: 小学 | 题目: 10题" style="-fx-font-size: 16; -fx-text-fill: #666666;"/>
|
||||
</VBox>
|
||||
|
||||
<!-- 答题详情区域 -->
|
||||
<ScrollPane fx:id="detailsScrollPane" fitToWidth="true" hbarPolicy="NEVER" vbarPolicy="AS_NEEDED"
|
||||
style="-fx-background-color: rgba(248,249,250,0.8); -fx-background-radius: 10; -fx-border-color: #E0E0E0; -fx-border-radius: 10; -fx-border-width: 1;"
|
||||
prefHeight="400" maxHeight="500">
|
||||
<content>
|
||||
<VBox fx:id="detailsContainer" spacing="15.0" style="-fx-padding: 20;">
|
||||
<!-- 详细信息将在这里动态添加 -->
|
||||
</VBox>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
|
||||
<!-- 滚动控制按钮区域 -->
|
||||
<HBox alignment="CENTER" spacing="15.0">
|
||||
<Button fx:id="scrollToTopButton" text="⬆️ 回到顶部" onAction="#handleScrollToTop" style="-fx-background-color: linear-gradient(to right, #4CAF50, #45a049); -fx-text-fill: white; -fx-background-radius: 8; -fx-padding: 8 15; -fx-font-size: 12; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 3, 0, 0, 1);"/>
|
||||
<Button fx:id="scrollToBottomButton" text="⬇️ 到底部" onAction="#handleScrollToBottom" style="-fx-background-color: linear-gradient(to right, #2196F3, #1976D2); -fx-text-fill: white; -fx-background-radius: 8; -fx-padding: 8 15; -fx-font-size: 12; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 3, 0, 0, 1);"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<HBox alignment="CENTER" spacing="20.0">
|
||||
<Button fx:id="closeButton" text="❌ 关闭" onAction="#handleClose" style="-fx-background-color: linear-gradient(to right, #DC143C, #B22222); -fx-text-fill: white; -fx-background-radius: 12; -fx-padding: 12 25; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.mathsystemtogether.ExamResultController">
|
||||
<children>
|
||||
<!-- 背景渐变 -->
|
||||
<AnchorPane style="-fx-background-color: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
||||
<children>
|
||||
<!-- 主要内容区域 -->
|
||||
<VBox alignment="CENTER" spacing="30.0" style="-fx-background-color: rgba(255,255,255,0.95); -fx-background-radius: 20; -fx-padding: 40; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 20, 0, 0, 5);" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="50.0">
|
||||
<children>
|
||||
<!-- 标题区域 -->
|
||||
<VBox alignment="CENTER" spacing="10.0">
|
||||
<Label fx:id="titleLabel" text="🎉 考试完成!" style="-fx-font-size: 36; -fx-font-weight: bold; -fx-text-fill: #2E8B57; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
<Label fx:id="subtitleLabel" text="恭喜您完成了数学考试" style="-fx-font-size: 18; -fx-text-fill: #666666;"/>
|
||||
</VBox>
|
||||
|
||||
<!-- 分数显示区域 -->
|
||||
<VBox alignment="CENTER" spacing="20.0" style="-fx-background-color: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); -fx-background-radius: 15; -fx-padding: 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 10, 0, 0, 3);">
|
||||
<children>
|
||||
<Label fx:id="scoreLabel" text="得分: 85分" style="-fx-font-size: 48; -fx-font-weight: bold; -fx-text-fill: white; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.5), 8, 0, 0, 2);"/>
|
||||
<HBox alignment="CENTER" spacing="40.0">
|
||||
<VBox alignment="CENTER" spacing="5.0">
|
||||
<Label fx:id="correctCountLabel" text="正确: 8题" style="-fx-font-size: 16; -fx-text-fill: white; -fx-font-weight: bold;"/>
|
||||
<Label text="正确题目" style="-fx-font-size: 12; -fx-text-fill: rgba(255,255,255,0.8);"/>
|
||||
</VBox>
|
||||
<VBox alignment="CENTER" spacing="5.0">
|
||||
<Label fx:id="totalCountLabel" text="总计: 10题" style="-fx-font-size: 16; -fx-text-fill: white; -fx-font-weight: bold;"/>
|
||||
<Label text="总题目" style="-fx-font-size: 12; -fx-text-fill: rgba(255,255,255,0.8);"/>
|
||||
</VBox>
|
||||
<VBox alignment="CENTER" spacing="5.0">
|
||||
<Label fx:id="accuracyLabel" text="正确率: 80%" style="-fx-font-size: 16; -fx-text-fill: white; -fx-font-weight: bold;"/>
|
||||
<Label text="准确率" style="-fx-font-size: 12; -fx-text-fill: rgba(255,255,255,0.8);"/>
|
||||
</VBox>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
<!-- 成绩评价区域 -->
|
||||
<VBox alignment="CENTER" spacing="10.0">
|
||||
<Label fx:id="gradeLabel" text="优秀" style="-fx-font-size: 24; -fx-font-weight: bold; -fx-text-fill: #2E8B57;"/>
|
||||
<Label fx:id="commentLabel" text="表现非常出色!继续保持!" style="-fx-font-size: 16; -fx-text-fill: #666666;"/>
|
||||
</VBox>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<HBox alignment="CENTER" spacing="30.0">
|
||||
<Button fx:id="continueButton" text="🔄 继续做题" onAction="#handleContinueExam" style="-fx-background-color: linear-gradient(to right, #32CD32, #228B22); -fx-text-fill: white; -fx-background-radius: 12; -fx-padding: 15 30; -fx-font-size: 16; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
<Button fx:id="exitButton" text="🚪 退出系统" onAction="#handleExitSystem" style="-fx-background-color: linear-gradient(to right, #DC143C, #B22222); -fx-text-fill: white; -fx-background-radius: 12; -fx-padding: 15 30; -fx-font-size: 16; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 详细信息按钮 -->
|
||||
<Button fx:id="detailsButton" text="📊 查看详细答题情况" onAction="#handleShowDetails" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC); -fx-text-fill: white; -fx-background-radius: 12; -fx-padding: 12 25; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
@ -1 +1,2 @@
|
||||
wgll|123456|ymhlovesLQX@163.com|小学|1760162416490
|
||||
wgll|Ymh123456|ymhlovesLQX@163.com|小学|1760162416490
|
||||
666|123456789|252436951@qq.com|小学|1760166999971
|
||||
|
||||
Loading…
Reference in new issue