Merge pull request '对前端长方法进行解耦,并使代码符合规范' (#12) from master into develop

pull/13/head
ppy4sjqvf 4 months ago
commit 773d83be67

@ -4,13 +4,30 @@ import com.wsf.mathapp.controller.SceneManager;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* .
* JavaFX.
*/
public class Main extends Application {
/**
* JavaFX.
* .
*
* @param primaryStage JavaFX.
*/
@Override
public void start(Stage primaryStage) {
SceneManager sceneManager = new SceneManager(primaryStage);
sceneManager.showLoginView();
}
/**
* .
* JavaFX.
*
* @param args .
*/
public static void main(String[] args) {
launch(args);
}

@ -1,12 +1,22 @@
package com.wsf.mathapp.controller;
import com.wsf.mathapp.view.*;
import com.wsf.mathapp.view.LevelSelectionView;
import com.wsf.mathapp.view.LoginView;
import com.wsf.mathapp.view.MainMenuView;
import com.wsf.mathapp.view.QuestionCountView;
import com.wsf.mathapp.view.QuizView;
import com.wsf.mathapp.view.RegisterView;
import com.wsf.mathapp.view.ResultView;
import javafx.stage.Stage;
/**
* .
* .
*/
public class SceneManager {
private final Stage primaryStage;
private final LoginView loginView;
private RegisterView registerView;
private final RegisterView registerView;
private final MainMenuView mainMenuView;
private final LevelSelectionView levelSelectionView;
private final QuestionCountView questionCountView;
@ -14,6 +24,11 @@ public class SceneManager {
private final ResultView resultView;
private String currentUserName;
/**
* .
*
* @param primaryStage JavaFX.
*/
public SceneManager(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("数学学习软件");
@ -29,6 +44,10 @@ public class SceneManager {
this.resultView = new ResultView(this);
}
/**
* .
* .
*/
public void showLoginView() {
System.out.println("切换到登录界面");
loginView.clearFields();
@ -36,6 +55,10 @@ public class SceneManager {
primaryStage.show();
}
/**
* .
* .
*/
public void showRegisterView() {
System.out.println("切换到注册界面");
registerView.clearFields();
@ -43,32 +66,54 @@ public class SceneManager {
primaryStage.show();
}
/**
* .
* .
*/
public void showMainMenuView() {
System.out.println("切换到主菜单界面");
// 在显示主菜单前更新用户名
if (mainMenuView != null) {
mainMenuView.updateUsername(currentUserName);
}
primaryStage.setScene(mainMenuView.getScene());
if (mainMenuView != null) {
primaryStage.setScene(mainMenuView.getScene());
}
primaryStage.show(); // 添加这行
}
/**
* .
* .
*/
public void showLevelSelectionView() {
System.out.println("切换到级别选择界面");
// 在显示级别选择界面前更新用户名
if (levelSelectionView != null) {
levelSelectionView.updateUsername(currentUserName);
}
primaryStage.setScene(levelSelectionView.getScene());
if (levelSelectionView != null) {
primaryStage.setScene(levelSelectionView.getScene());
}
primaryStage.show(); // 添加这行
}
/**
* .
* .
*/
public void showQuestionCountView() {
System.out.println("切换到题目数量选择界面");
primaryStage.setScene(questionCountView.getScene());
primaryStage.show(); // 添加这行
}
/**
* .
*
* @param level .
* @param count .
*/
public void showQuizView(String level, int count) {
System.out.println("切换到答题界面 - 级别: " + level + ", 题目数量: " + count);
// 设置测验参数
@ -77,6 +122,11 @@ public class SceneManager {
primaryStage.show();
}
/**
* .
* @param score .
*/
public void showResultView(double score) {
System.out.println("切换到结果界面,分数: " + score);
resultView.setScore(score);
@ -84,20 +134,30 @@ public class SceneManager {
primaryStage.show(); // 添加这行
}
// Getter methods for views
public LoginView getLoginView() { return loginView; }
public RegisterView getRegisterView() { return registerView; }
public MainMenuView getMainMenuView() { return mainMenuView; }
public LevelSelectionView getLevelSelectionView() { return levelSelectionView; }
public QuestionCountView getQuestionCountView() { return questionCountView; }
public QuizView getQuizView() { return quizView; }
public ResultView getResultView() { return resultView; }
/**
* .
*
* @return QuestionCountView .
*/
public QuestionCountView getQuestionCountView() {
return questionCountView;
}
/**
* .
*
* @param currentUserName .
*/
public void setCurrentUserName(String currentUserName) {
this.currentUserName = currentUserName;
System.out.println("设置当前用户名: " + currentUserName);
}
/**
* .
*
* @return String .
*/
public String getCurrentUserName() {
return this.currentUserName;
}

@ -1,14 +1,21 @@
package com.wsf.mathapp.service;
import com.ybw.mathapp.service.PrimarySchoolGenerator;
import com.ybw.mathapp.service.JuniorHighGenerator;
import com.ybw.mathapp.service.SeniorHighGenerator;
import com.ybw.mathapp.service.PrimarySchoolGenerator;
import com.ybw.mathapp.service.QuestionGenerator;
import com.ybw.mathapp.service.SeniorHighGenerator;
/**
* .
*/
public class QuestionService {
/**
* .
*
* @param level "小学""初中""高中".
* @return QuestionGenerator null.
*/
public static QuestionGenerator createGenerator(String level) {
return switch (level) {
case "小学" -> new PrimarySchoolGenerator();

@ -16,6 +16,10 @@ import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
/**
* .
* .
*/
public class LevelSelectionView {
private Scene scene;
private final SceneManager sceneManager;
@ -25,12 +29,20 @@ public class LevelSelectionView {
private Label usernameLabel;
private Text avatarText;
/**
* .
*
* @param sceneManager .
*/
public LevelSelectionView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
this.currentUsername = sceneManager.getCurrentUserName();
createScene();
}
/**
* .
*/
private void createScene() {
// 创建主容器
VBox mainContainer = new VBox();
@ -47,31 +59,45 @@ public class LevelSelectionView {
scene = new Scene(mainContainer, 450, 550);
}
/**
* .
*
* @return HBox .
*/
private HBox createUserInfoBar() {
HBox userInfoBar = new HBox(15);
userInfoBar.setAlignment(Pos.CENTER_LEFT);
userInfoBar.setPadding(new Insets(0, 0, 30, 0));
userInfoBar.setStyle("-fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;");
userInfoBar.setStyle("-fx-border-color: #e0e0e0; "
+ "-fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;");
// 用户名标签
usernameLabel = new Label(currentUsername != null ? currentUsername : "用户");
usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
usernameLabel.setStyle("-fx-text-fill: #2c3e50;");
// 间隔
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
// 创建头像容器
VBox avatarContainer = createAvatarContainer();
userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer);
return userInfoBar;
}
// 创建圆形头像容器
/**
* .
*
* @return VBox .
*/
private VBox createAvatarContainer() {
VBox avatarContainer = new VBox();
avatarContainer.setAlignment(Pos.CENTER);
avatarContainer.setPrefSize(50, 50);
// 创建圆形头像背景
Circle avatarCircle = new Circle(22);
avatarCircle.setFill(Color.web("#4CAF50")); // 统一的绿色背景
avatarCircle.setStroke(Color.WHITE);
avatarCircle.setStrokeWidth(2);
// 添加阴影效果
avatarCircle.setStyle("-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);");
// 添加首字母文本
avatarText = new Text(getFirstLetter());
avatarText.setFill(Color.WHITE);
avatarText.setFont(Font.font("Arial", FontWeight.BOLD, 16));
// 创建圆形头像背景
Circle avatarCircle = createAvatarCircle();
// 使用StackPane将文本放在圆形中心
javafx.scene.layout.StackPane avatarStack = new javafx.scene.layout.StackPane();
avatarStack.getChildren().addAll(avatarCircle, avatarText);
@ -79,101 +105,190 @@ public class LevelSelectionView {
avatarStack.setAlignment(Pos.CENTER);
avatarContainer.getChildren().add(avatarStack);
return avatarContainer;
}
// 用户名标签
usernameLabel = new Label(currentUsername != null ? currentUsername : "用户");
usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
usernameLabel.setStyle("-fx-text-fill: #2c3e50;");
// 间隔
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer);
/**
* .
*
* @return Circle .
*/
private Circle createAvatarCircle() {
Circle avatarCircle = new Circle(22);
avatarCircle.setFill(Color.web("#4CAF50")); // 统一的绿色背景
avatarCircle.setStroke(Color.WHITE);
avatarCircle.setStrokeWidth(2);
return userInfoBar;
// 添加阴影效果
avatarCircle.setStyle("-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);");
return avatarCircle;
}
/**
* .
*
* @return VBox .
*/
private VBox createSelectionContent() {
VBox selectionContent = new VBox(25);
selectionContent.setPadding(new Insets(30, 20, 20, 20));
selectionContent.setAlignment(Pos.CENTER);
// 创建标题区域
VBox titleSection = createTitleSection();
// 创建级别按钮区域
VBox levelButtonsSection = createLevelButtonsSection();
// 创建返回按钮
Button backButton = createBackButton();
selectionContent.getChildren().addAll(titleSection, levelButtonsSection, backButton);
return selectionContent;
}
/**
* .
*
* @return VBox .
*/
private VBox createTitleSection() {
VBox titleSection = new VBox(5);
titleSection.setAlignment(Pos.CENTER);
Label titleLabel = new Label("选择题目级别");
titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 26));
titleLabel.setStyle("-fx-text-fill: #2c3e50;");
// 添加副标题
Label subtitleLabel = new Label("请选择适合您的学习级别");
subtitleLabel.setFont(Font.font("Arial", 14));
subtitleLabel.setStyle("-fx-text-fill: #7f8c8d; -fx-padding: 0 0 10 0;");
titleSection.getChildren().addAll(titleLabel, subtitleLabel);
return titleSection;
}
/**
* .
*
* @return VBox .
*/
private VBox createLevelButtonsSection() {
VBox levelButtonsSection = new VBox(15);
levelButtonsSection.setAlignment(Pos.CENTER);
Button primaryButton = createLevelButton("小学题目", "#4CAF50", "#45a049");
Button juniorButton = createLevelButton("初中题目", "#2196F3", "#1976D2");
Button seniorButton = createLevelButton("高中题目", "#9C27B0", "#7B1FA2");
Button backButton = new Button("返回主菜单");
backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;");
backButton.setPrefSize(180, 45);
backButton.setOnMouseEntered(e -> backButton.setStyle("-fx-background-color: #7f8c8d; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;"));
backButton.setOnMouseExited(e -> backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;"));
setupLevelButtonAction(primaryButton, "小学");
setupLevelButtonAction(juniorButton, "初中");
setupLevelButtonAction(seniorButton, "高中");
primaryButton.setOnAction(e -> {
String selectedLevel = "小学";
sceneManager.getQuestionCountView().setLevel(selectedLevel);
sceneManager.showQuestionCountView();
});
juniorButton.setOnAction(e -> {
String selectedLevel = "初中";
sceneManager.getQuestionCountView().setLevel(selectedLevel);
sceneManager.showQuestionCountView();
});
levelButtonsSection.getChildren().addAll(primaryButton, juniorButton, seniorButton);
return levelButtonsSection;
}
seniorButton.setOnAction(e -> {
String selectedLevel = "高中";
sceneManager.getQuestionCountView().setLevel(selectedLevel);
/**
* .
*
* @param button .
* @param level .
*/
private void setupLevelButtonAction(Button button, String level) {
button.setOnAction(e -> {
sceneManager.getQuestionCountView().setLevel(level);
sceneManager.showQuestionCountView();
});
}
backButton.setOnAction(e -> {
sceneManager.showMainMenuView();
});
selectionContent.getChildren().addAll(
titleLabel, subtitleLabel, primaryButton, juniorButton, seniorButton, backButton
);
/**
* .
*
* @return Button .
*/
private Button createBackButton() {
Button backButton = new Button("返回主菜单");
backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: "
+ "white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;");
backButton.setPrefSize(180, 45);
setupButtonHoverEffect(backButton, "#95a5a6", "#7f8c8d");
backButton.setOnAction(e -> sceneManager.showMainMenuView());
return selectionContent;
return backButton;
}
/**
* .
*
* @param text .
* @param color .
* @param hoverColor .
* @return Button .
*/
private Button createLevelButton(String text, String color, String hoverColor) {
Button button = new Button(text);
button.setStyle(String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " +
"-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);",
"-fx-background-color: %s; -fx-text-fill: "
+ "white; -fx-font-size: 16px; -fx-font-weight: bold;-fx-background-radius: 12;"
+ "-fx-padding: 12 30;-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);",
color
));
button.setPrefSize(220, 60);
button.setOnMouseEntered(e -> button.setStyle(String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " +
"-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0.4, 3, 3);",
hoverColor
)));
button.setOnMouseExited(e -> button.setStyle(String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " +
"-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);",
color
)));
setupButtonHoverEffect(button, color, hoverColor);
return button;
}
/**
* .
*
* @param button .
* @param normalColor .
* @param hoverColor .
*/
private void setupButtonHoverEffect(Button button, String normalColor, String hoverColor) {
String normalStyle = String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: %s;"
+ " -fx-background-radius: %s; -fx-padding: %s; -fx-effect: "
+ "dropshadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);",
normalColor,
button.getStyle().contains("16px") ? "16px" : "14px",
button.getStyle().contains("12") ? "12" : "8",
button.getStyle().contains("12 30") ? "12 30" : "8 20"
);
String hoverStyle = String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: %s;"
+ " -fx-background-radius: %s; -fx-padding: %s; -fx-effect:"
+ " dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0.4, 3, 3);",
hoverColor,
button.getStyle().contains("16px") ? "16px" : "14px",
button.getStyle().contains("12") ? "12" : "8",
button.getStyle().contains("12 30") ? "12 30" : "8 20"
);
button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
button.setOnMouseExited(e -> button.setStyle(normalStyle));
}
/**
* .
*
* @return String "U".
*/
private String getFirstLetter() {
return currentUsername != null && !currentUsername.isEmpty() ?
currentUsername.substring(0, 1).toUpperCase() : "U";
return currentUsername != null && !currentUsername.isEmpty()
? currentUsername.substring(0, 1).toUpperCase() : "U";
}
// 添加更新用户名的方法
/**
* .
*
* @param username .
*/
public void updateUsername(String username) {
this.currentUsername = username;
if (usernameLabel != null) {
@ -184,6 +299,11 @@ public class LevelSelectionView {
}
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}

@ -3,14 +3,20 @@ package com.wsf.mathapp.view;
import com.wsf.mathapp.controller.SceneManager;
import com.ybw.mathapp.util.Login;
import com.ybw.mathapp.util.LoginFileUtils;
import com.ybw.mathapp.util.Register;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
/**
* .
* .
*/
public class LoginView {
private Scene scene;
private final SceneManager sceneManager;
@ -20,90 +26,206 @@ public class LoginView {
private PasswordField passwordField;
private Label statusLabel;
/**
* .
*
* @param sceneManager .
*/
public LoginView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
createScene();
}
/**
* .
*/
private void createScene() {
VBox root = new VBox(20);
root.setPadding(new Insets(40));
root.setAlignment(Pos.CENTER);
// 创建用户名/邮箱输入框
usernameOrEmailField = createUsernameField();
// 创建密码输入框
passwordField = createPasswordField();
// 创建登录按钮
Button loginButton = createLoginButton();
// 创建注册按钮
Button registerButton = createRegisterButton();
// 创建状态标签
statusLabel = new Label();
// 设置按钮事件
setupLoginButtonAction(loginButton);
setupRegisterButtonAction(registerButton);
// 添加回车键登录支持
setupEnterKeySupport(loginButton);
// 创建界面标题
Label titleLabel = createTitleLabel();
// 创建副标题
Label subtitleLabel = createSubtitleLabel();
root.getChildren().addAll(
titleLabel, subtitleLabel, usernameOrEmailField, passwordField,
loginButton, registerButton, statusLabel
);
scene = new Scene(root, 400, 500);
}
/**
* .
*
* @return Label .
*/
private Label createTitleLabel() {
Label titleLabel = new Label("数学学习软件");
titleLabel.setFont(Font.font(24));
return titleLabel;
}
/**
* .
*
* @return Label .
*/
private Label createSubtitleLabel() {
Label subtitleLabel = new Label("用户登录");
subtitleLabel.setFont(Font.font(18));
return subtitleLabel;
}
// 修改提示文本
usernameOrEmailField = new TextField();
usernameOrEmailField.setPromptText("请输入用户名或邮箱");
usernameOrEmailField.setMaxWidth(300);
usernameOrEmailField.setPrefHeight(40);
/**
* /.
*
* @return TextField /.
*/
private TextField createUsernameField() {
TextField field = new TextField();
field.setPromptText("请输入用户名或邮箱");
field.setMaxWidth(300);
field.setPrefHeight(40);
return field;
}
passwordField = new PasswordField();
passwordField.setPromptText("请输入密码");
passwordField.setMaxWidth(300);
passwordField.setPrefHeight(40);
/**
* .
*
* @return PasswordField .
*/
private PasswordField createPasswordField() {
PasswordField field = new PasswordField();
field.setPromptText("请输入密码");
field.setMaxWidth(300);
field.setPrefHeight(40);
return field;
}
Button loginButton = new Button("登录");
loginButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 14px;");
loginButton.setPrefSize(300, 40);
/**
* .
*
* @return Button .
*/
private Button createLoginButton() {
Button button = new Button("登录");
button.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 14px;");
button.setPrefSize(300, 40);
return button;
}
Button registerButton = new Button("注册账号");
registerButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 14px;");
registerButton.setPrefSize(300, 40);
/**
* .
*
* @return Button .
*/
private Button createRegisterButton() {
Button button = new Button("注册账号");
button.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 14px;");
button.setPrefSize(300, 40);
return button;
}
statusLabel = new Label();
/**
* .
*
* @param loginButton .
*/
private void setupLoginButtonAction(Button loginButton) {
loginButton.setOnAction(e -> handleLogin());
}
loginButton.setOnAction(e -> {
String usernameOrEmail = usernameOrEmailField.getText().trim();
String password = passwordField.getText();
if (usernameOrEmail.isEmpty() || password.isEmpty()) {
showError(statusLabel, "用户名/邮箱和密码不能为空!");
return;
}
// 调用后端的登录方法,支持用户名或邮箱登录
boolean success = Login.login(usernameOrEmail, password);
System.out.println(usernameOrEmail);
System.out.println(password);
if (success) {
showSuccess(statusLabel);
String username;
if (LoginFileUtils.emailFindName(usernameOrEmail) == null){
username = usernameOrEmail;
}
else {
username = LoginFileUtils.emailFindName(usernameOrEmail);
}
sceneManager.setCurrentUserName(username);
sceneManager.showMainMenuView();
} else {
showError(statusLabel, "用户名/邮箱或密码错误!");
}
});
registerButton.setOnAction(e -> {
sceneManager.showRegisterView();
});
/**
* .
*
* @param registerButton .
*/
private void setupRegisterButtonAction(Button registerButton) {
registerButton.setOnAction(e -> sceneManager.showRegisterView());
}
// 添加回车键登录支持
/**
* .
*
* @param loginButton .
*/
private void setupEnterKeySupport(Button loginButton) {
usernameOrEmailField.setOnAction(e -> loginButton.fire());
passwordField.setOnAction(e -> loginButton.fire());
}
root.getChildren().addAll(
titleLabel, subtitleLabel, usernameOrEmailField, passwordField,
loginButton, registerButton, statusLabel
);
/**
* .
*/
private void handleLogin() {
String usernameOrEmail = usernameOrEmailField.getText().trim();
String password = passwordField.getText();
scene = new Scene(root, 400, 500);
if (usernameOrEmail.isEmpty() || password.isEmpty()) {
showError(statusLabel, "用户名/邮箱和密码不能为空!");
return;
}
// 调用后端的登录方法,支持用户名或邮箱登录
boolean success = Login.login(usernameOrEmail, password);
System.out.println(usernameOrEmail);
System.out.println(password);
if (success) {
handleLoginSuccess(usernameOrEmail);
} else {
showError(statusLabel, "用户名/邮箱或密码错误!");
}
}
/**
* .
*
* @param usernameOrEmail 使.
*/
private void handleLoginSuccess(String usernameOrEmail) {
showSuccess(statusLabel);
String username = getUsernameFromInput(usernameOrEmail);
sceneManager.setCurrentUserName(username);
sceneManager.showMainMenuView();
}
/**
* .
*
* @param usernameOrEmail .
* @return String .
*/
private String getUsernameFromInput(String usernameOrEmail) {
String foundName = LoginFileUtils.emailFindName(usernameOrEmail);
return foundName == null ? usernameOrEmail : foundName;
}
/**
*
* .
*/
public void clearFields() {
usernameOrEmailField.clear();
@ -111,16 +233,32 @@ public class LoginView {
statusLabel.setText("");
}
/**
* .
*
* @param label .
* @param message .
*/
private void showError(Label label, String message) {
label.setText(message);
label.setStyle("-fx-text-fill: red;");
}
/**
* .
*
* @param label .
*/
private void showSuccess(Label label) {
label.setText("登录成功!");
label.setStyle("-fx-text-fill: green;");
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}

@ -20,6 +20,10 @@ import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
/**
* .
* 退.
*/
public class MainMenuView {
private Scene scene;
private final SceneManager sceneManager;
@ -30,12 +34,20 @@ public class MainMenuView {
private Text avatarText;
private Label welcomeLabel;
/**
* .
*
* @param sceneManager .
*/
public MainMenuView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
this.currentUsername = sceneManager.getCurrentUserName();
createScene();
}
/**
* .
*/
private void createScene() {
// 创建主容器
VBox mainContainer = new VBox();
@ -52,111 +64,237 @@ public class MainMenuView {
scene = new Scene(mainContainer, 450, 550);
}
/**
* .
*
* @return HBox .
*/
private HBox createUserInfoBar() {
HBox userInfoBar = new HBox(15);
userInfoBar.setAlignment(Pos.CENTER_LEFT);
userInfoBar.setPadding(new Insets(0, 0, 30, 0));
userInfoBar.setStyle("-fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;");
userInfoBar.setStyle("-fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0; "
+ "-fx-padding: 0 0 15 0;");
// 创建圆形头像容器
// 用户名标签
usernameLabel = new Label(currentUsername != null ? currentUsername : "用户");
usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
usernameLabel.setStyle("-fx-text-fill: #2c3e50;");
// 间隔
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
// 创建头像容器
VBox avatarContainer = createAvatarContainer();
userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer);
return userInfoBar;
}
/**
* .
*
* @return VBox .
*/
private VBox createAvatarContainer() {
VBox avatarContainer = new VBox();
avatarContainer.setAlignment(Pos.CENTER);
avatarContainer.setPrefSize(50, 50);
// 创建圆形头像背景
Circle avatarCircle = new Circle(22);
avatarCircle.setFill(Color.web("#4CAF50"));
avatarCircle.setStroke(Color.WHITE);
avatarCircle.setStrokeWidth(2);
// 添加阴影效果
avatarCircle.setStyle("-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);");
// 添加首字母文本
avatarText = new Text(getFirstLetter());
avatarText.setFill(Color.WHITE);
avatarText.setFont(Font.font("Arial", FontWeight.BOLD, 16));
// 创建圆形头像背景
Circle avatarCircle = createAvatarCircle();
// 使用StackPane将文本放在圆形中心
javafx.scene.layout.StackPane avatarStack = new javafx.scene.layout.StackPane();
javafx.scene.layout.StackPane avatarStack =
new javafx.scene.layout.StackPane();
avatarStack.getChildren().addAll(avatarCircle, avatarText);
avatarStack.setPrefSize(44, 44);
avatarStack.setAlignment(Pos.CENTER);
avatarContainer.getChildren().add(avatarStack);
return avatarContainer;
}
// 用户名标签
usernameLabel = new Label(currentUsername != null ? currentUsername : "用户");
usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
usernameLabel.setStyle("-fx-text-fill: #2c3e50;");
// 间隔
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer);
/**
* .
*
* @return Circle .
*/
private Circle createAvatarCircle() {
Circle avatarCircle = new Circle(22);
avatarCircle.setFill(Color.web("#4CAF50"));
avatarCircle.setStroke(Color.WHITE);
avatarCircle.setStrokeWidth(2);
return userInfoBar;
// 添加阴影效果
avatarCircle.setStyle("-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), "
+ "5, 0.3, 2, 2);");
return avatarCircle;
}
/**
* .
*
* @return VBox .
*/
private VBox createMenuContent() {
VBox menuContent = new VBox(25);
menuContent.setPadding(new Insets(20));
menuContent.setAlignment(Pos.CENTER);
// 创建标题区域
VBox titleSection = createTitleSection();
// 创建功能按钮区域
VBox buttonSection = createButtonSection();
menuContent.getChildren().addAll(titleSection, buttonSection);
return menuContent;
}
/**
* .
*
* @return VBox .
*/
private VBox createTitleSection() {
VBox titleSection = new VBox(10);
titleSection.setAlignment(Pos.CENTER);
Label titleLabel = new Label("数学学习软件");
titleLabel.setFont(Font.font(28));
titleLabel.setStyle("-fx-text-fill: #2c3e50;");
// 修改欢迎标签,显示用户名
welcomeLabel = new Label("欢迎," + (currentUsername != null ? currentUsername : "用户") + "");
welcomeLabel = new Label("欢迎,"
+ (currentUsername != null ? currentUsername : "用户") + "");
welcomeLabel.setFont(Font.font(18));
welcomeLabel.setStyle("-fx-text-fill: #7f8c8d;");
Button startButton = new Button("开始练习");
startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;");
startButton.setPrefSize(220, 55);
startButton.setOnMouseEntered(e -> startButton.setStyle("-fx-background-color: #45a049; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"));
startButton.setOnMouseExited(e -> startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"));
Button changePasswordButton = new Button("修改密码");
changePasswordButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;");
changePasswordButton.setPrefSize(220, 55);
changePasswordButton.setOnMouseEntered(e -> changePasswordButton.setStyle("-fx-background-color: #1976D2; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"));
changePasswordButton.setOnMouseExited(e -> changePasswordButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"));
Button logoutButton = new Button("退出登录");
logoutButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;");
logoutButton.setPrefSize(220, 55);
logoutButton.setOnMouseEntered(e -> logoutButton.setStyle("-fx-background-color: #d32f2f; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"));
logoutButton.setOnMouseExited(e -> logoutButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"));
startButton.setOnAction(e -> {
sceneManager.showLevelSelectionView();
});
titleSection.getChildren().addAll(titleLabel, welcomeLabel);
return titleSection;
}
changePasswordButton.setOnAction(e -> {
showChangePasswordDialog();
});
/**
* .
*
* @return VBox .
*/
private VBox createButtonSection() {
VBox buttonSection = new VBox(15);
buttonSection.setAlignment(Pos.CENTER);
logoutButton.setOnAction(e -> {
sceneManager.showLoginView();
});
Button startButton = createStartButton();
Button changePasswordButton = createChangePasswordButton();
Button logoutButton = createLogoutButton();
setupButtonActions(startButton, changePasswordButton, logoutButton);
menuContent.getChildren().addAll(
titleLabel, welcomeLabel, startButton,
changePasswordButton, logoutButton
buttonSection.getChildren().addAll(
startButton, changePasswordButton, logoutButton
);
return menuContent;
return buttonSection;
}
/**
* .
*
* @return Button .
*/
private Button createStartButton() {
Button button = new Button("开始练习");
button.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; "
+ "-fx-font-size: 16px; -fx-background-radius: 10;");
button.setPrefSize(220, 55);
setupButtonHoverEffect(button, "#4CAF50", "#45a049");
return button;
}
/**
* .
*
* @return Button .
*/
private Button createChangePasswordButton() {
Button button = new Button("修改密码");
button.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; "
+ "-fx-font-size: 16px; -fx-background-radius: 10;");
button.setPrefSize(220, 55);
setupButtonHoverEffect(button, "#2196F3", "#1976D2");
return button;
}
/**
* 退.
*
* @return Button 退.
*/
private Button createLogoutButton() {
Button button = new Button("退出登录");
button.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; "
+ "-fx-font-size: 16px; -fx-background-radius: 10;");
button.setPrefSize(220, 55);
setupButtonHoverEffect(button, "#f44336", "#d32f2f");
return button;
}
/**
* .
*
* @param button .
* @param normalColor .
* @param hoverColor .
*/
private void setupButtonHoverEffect(Button button, String normalColor,
String hoverColor) {
String normalStyle = String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; "
+ "-fx-background-radius: 10;", normalColor);
String hoverStyle = String.format(
"-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; "
+ "-fx-background-radius: 10;", hoverColor);
button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
button.setOnMouseExited(e -> button.setStyle(normalStyle));
}
/**
* .
*
* @param startButton .
* @param changePasswordButton .
* @param logoutButton 退.
*/
private void setupButtonActions(Button startButton,
Button changePasswordButton, Button logoutButton) {
startButton.setOnAction(e -> sceneManager.showLevelSelectionView());
changePasswordButton.setOnAction(e -> showChangePasswordDialog());
logoutButton.setOnAction(e -> sceneManager.showLoginView());
}
/**
* .
*
* @return String "U".
*/
private String getFirstLetter() {
return currentUsername != null && !currentUsername.isEmpty() ?
currentUsername.substring(0, 1).toUpperCase() : "U";
return currentUsername != null && !currentUsername.isEmpty()
? currentUsername.substring(0, 1).toUpperCase() : "U";
}
// 添加更新用户名的方法
/**
* .
*
* @param username .
*/
public void updateUsername(String username) {
this.currentUsername = username;
if (usernameLabel != null) {
@ -170,28 +308,60 @@ public class MainMenuView {
}
}
/**
* .
*/
private void showChangePasswordDialog() {
// 创建修改密码对话框
javafx.scene.control.Dialog<Void> dialog = new javafx.scene.control.Dialog<>();
javafx.scene.control.Dialog<Void> dialog =
new javafx.scene.control.Dialog<>();
dialog.setTitle("修改密码");
dialog.setHeaderText("请输入密码信息");
dialog.setGraphic(null); // 移除默认图标
// 创建表单
javafx.scene.layout.GridPane grid = createPasswordForm();
dialog.getDialogPane().setContent(grid);
// 添加按钮
dialog.getDialogPane().getButtonTypes().addAll(
javafx.scene.control.ButtonType.OK,
javafx.scene.control.ButtonType.CANCEL
);
dialog.setResultConverter(dialogButton -> {
if (dialogButton == javafx.scene.control.ButtonType.OK) {
handlePasswordChange(grid);
}
return null;
});
dialog.showAndWait();
}
/**
* .
*
* @return GridPane .
*/
private javafx.scene.layout.GridPane createPasswordForm() {
javafx.scene.layout.GridPane grid = new javafx.scene.layout.GridPane();
grid.setHgap(15);
grid.setVgap(15);
grid.setPadding(new Insets(20, 30, 10, 30));
javafx.scene.control.PasswordField oldPassword = new javafx.scene.control.PasswordField();
javafx.scene.control.PasswordField oldPassword =
new javafx.scene.control.PasswordField();
oldPassword.setPromptText("请输入原密码");
oldPassword.setPrefWidth(200);
javafx.scene.control.PasswordField newPassword = new javafx.scene.control.PasswordField();
newPassword.setPromptText("请输入新密码密码要6-10位包含大小写字母和数字");
javafx.scene.control.PasswordField newPassword =
new javafx.scene.control.PasswordField();
newPassword.setPromptText("请输入新密码密码要6-10位"
+ "包含大,小写字母和数字)");
newPassword.setPrefWidth(200);
javafx.scene.control.PasswordField confirmPassword = new javafx.scene.control.PasswordField();
javafx.scene.control.PasswordField confirmPassword =
new javafx.scene.control.PasswordField();
confirmPassword.setPromptText("请确认新密码");
confirmPassword.setPrefWidth(200);
@ -202,52 +372,76 @@ public class MainMenuView {
grid.add(new Label("确认密码:"), 0, 2);
grid.add(confirmPassword, 1, 2);
dialog.getDialogPane().setContent(grid);
return grid;
}
// 添加按钮
dialog.getDialogPane().getButtonTypes().addAll(
javafx.scene.control.ButtonType.OK,
javafx.scene.control.ButtonType.CANCEL
);
/**
* .
*
* @param grid .
*/
private void handlePasswordChange(javafx.scene.layout.GridPane grid) {
javafx.scene.control.PasswordField oldPassword =
(javafx.scene.control.PasswordField) grid.getChildren().get(1);
javafx.scene.control.PasswordField newPassword =
(javafx.scene.control.PasswordField) grid.getChildren().get(3);
javafx.scene.control.PasswordField confirmPassword =
(javafx.scene.control.PasswordField) grid.getChildren().get(5);
String oldPwd = oldPassword.getText();
String newPwd = newPassword.getText();
String confirmPwd = confirmPassword.getText();
if (!validatePasswordInput(oldPwd, newPwd, confirmPwd)) {
return;
}
dialog.setResultConverter(dialogButton -> {
if (dialogButton == javafx.scene.control.ButtonType.OK) {
// 这里可以添加修改密码的逻辑
String oldPwd = oldPassword.getText();
String newPwd = newPassword.getText();
String confirmPwd = confirmPassword.getText();
if (oldPwd.isEmpty() || newPwd.isEmpty() || confirmPwd.isEmpty()) {
showAlert("错误", "请填写所有密码字段!");
return null;
}
if (!Login.login(currentUsername,oldPwd)){
showAlert("错误", "原密码错误!");
return null;
}
if (!newPwd.equals(confirmPwd)) {
showAlert("错误", "两次输入的新密码不一致!");
return null;
}
if (!Register.isVaildPassword(newPwd)) {
showAlert("错误", "密码要6-10位包含大小写字母和数字");
return null;
}
// 调用修改密码的后端逻辑
if(!ChangePassword.changePassword(currentUsername, confirmPwd)){
showAlert("错误", "密码修改失败");
return null;
}
else{
showAlert("成功", "密码修改成功!");
}
}
return null;
});
if (!Login.login(currentUsername, oldPwd)) {
showAlert("错误", "原密码错误!");
return;
}
dialog.showAndWait();
if (!Register.isVaildPassword(newPwd)) {
showAlert("错误", "密码要6-10位包含大小写字母和数字");
return;
}
if (!ChangePassword.changePassword(currentUsername, confirmPwd)) {
showAlert("错误", "密码修改失败");
} else {
showAlert("成功", "密码修改成功!");
}
}
/**
* .
*
* @param oldPwd .
* @param newPwd .
* @param confirmPwd .
* @return boolean .
*/
private boolean validatePasswordInput(String oldPwd, String newPwd,
String confirmPwd) {
if (oldPwd.isEmpty() || newPwd.isEmpty() || confirmPwd.isEmpty()) {
showAlert("错误", "请填写所有密码字段!");
return false;
}
if (!newPwd.equals(confirmPwd)) {
showAlert("错误", "两次输入的新密码不一致!");
return false;
}
return true;
}
/**
* .
*
* @param title .
* @param message .
*/
private void showAlert(String title, String message) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle(title);
@ -256,6 +450,11 @@ public class MainMenuView {
alert.showAndWait();
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}

@ -4,82 +4,191 @@ import com.wsf.mathapp.controller.SceneManager;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
/**
* .
* 10-30.
*/
public class QuestionCountView {
private Scene scene;
private final SceneManager sceneManager;
private String level;
/**
* .
*
* @param sceneManager .
*/
public QuestionCountView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
createScene();
}
/**
* .
*/
private void createScene() {
VBox root = new VBox(20);
root.setPadding(new Insets(40));
root.setAlignment(Pos.CENTER);
// 创建标题标签
Label titleLabel = createTitleLabel();
// 创建级别显示标签
Label levelLabel = createLevelLabel();
// 创建数量输入框
TextField countField = createCountField();
// 创建开始答题按钮
Button startButton = createStartButton();
// 创建返回按钮
Button backButton = createBackButton();
// 创建状态标签
Label statusLabel = new Label();
// 设置按钮事件
setupStartButtonAction(startButton, countField, statusLabel);
setupBackButtonAction(backButton);
root.getChildren().addAll(
titleLabel, levelLabel, countField, startButton, backButton, statusLabel
);
scene = new Scene(root, 400, 400);
}
/**
* .
*
* @return Label .
*/
private Label createTitleLabel() {
Label titleLabel = new Label("选择题目数量");
titleLabel.setFont(Font.font(20));
return titleLabel;
}
/**
* .
*
* @return Label .
*/
private Label createLevelLabel() {
Label levelLabel = new Label();
levelLabel.setFont(Font.font(16));
return levelLabel;
}
/**
* .
*
* @return TextField .
*/
private TextField createCountField() {
TextField countField = new TextField();
countField.setPromptText("请输入题目数量 (10-30)");
countField.setMaxWidth(250);
countField.setPrefHeight(40);
return countField;
}
/**
* .
*
* @return Button .
*/
private Button createStartButton() {
Button startButton = new Button("开始答题");
startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 14px;");
startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; "
+ "-fx-font-size: 14px;");
startButton.setPrefSize(250, 45);
return startButton;
}
/**
* .
*
* @return Button .
*/
private Button createBackButton() {
Button backButton = new Button("返回");
backButton.setStyle("-fx-background-color: #757575; -fx-text-fill: white;");
backButton.setPrefSize(250, 40);
return backButton;
}
Label statusLabel = new Label();
/**
* .
*
* @param startButton .
* @param countField .
* @param statusLabel .
*/
private void setupStartButtonAction(Button startButton, TextField countField,
Label statusLabel) {
startButton.setOnAction(e -> handleStartQuiz(countField, statusLabel));
}
/**
* .
*
* @param backButton .
*/
private void setupBackButtonAction(Button backButton) {
backButton.setOnAction(e -> sceneManager.showLevelSelectionView());
}
startButton.setOnAction(e -> {
try {
String countText = countField.getText().trim();
if (countText.isEmpty()) {
showError(statusLabel, "请输入题目数量!");
return;
}
int count = Integer.parseInt(countText);
if (count < 10 || count > 30) {
showError(statusLabel, "题目数量必须在10-30之间");
return;
}
// 直接调用 showQuizView 并传递参数
sceneManager.showQuizView(level, count);
} catch (NumberFormatException ex) {
showError(statusLabel, "请输入有效的数字!");
/**
* .
*
* @param countField .
* @param statusLabel .
*/
private void handleStartQuiz(TextField countField, Label statusLabel) {
try {
String countText = countField.getText().trim();
if (countText.isEmpty()) {
showError(statusLabel, "请输入题目数量!");
return;
}
});
backButton.setOnAction(e -> {
sceneManager.showLevelSelectionView();
});
int count = Integer.parseInt(countText);
if (count < 10 || count > 30) {
showError(statusLabel, "题目数量必须在10-30之间");
return;
}
root.getChildren().addAll(
titleLabel, levelLabel, countField, startButton, backButton, statusLabel
);
// 直接调用 showQuizView 并传递参数
sceneManager.showQuizView(level, count);
scene = new Scene(root, 400, 400);
} catch (NumberFormatException ex) {
showError(statusLabel, "请输入有效的数字!");
}
}
/**
* .
*
* @param level .
*/
public void setLevel(String level) {
this.level = level;
// 更新界面显示当前选择的级别
updateLevelDisplay();
}
/**
* .
*/
private void updateLevelDisplay() {
if (scene != null) {
VBox root = (VBox) scene.getRoot();
Label levelLabel = (Label) root.getChildren().get(1);
@ -88,11 +197,22 @@ public class QuestionCountView {
}
}
/**
* .
*
* @param label .
* @param message .
*/
private void showError(Label label, String message) {
label.setText(message);
label.setStyle("-fx-text-fill: red;");
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}

@ -5,18 +5,25 @@ import com.wsf.mathapp.service.QuestionService;
import com.ybw.mathapp.entity.QuestionWithOptions;
import com.ybw.mathapp.service.MultipleChoiceGenerator;
import com.ybw.mathapp.service.QuestionGenerator;
import java.util.List;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import java.util.List;
/**
* .
* .
*/
public class QuizView {
private Scene scene;
private final SceneManager sceneManager;
private MultipleChoiceGenerator multipleChoiceGenerator = null;
private String currentLevel;
private int questionCount;
private List<QuestionWithOptions> questions;
@ -29,43 +36,105 @@ public class QuizView {
private Label progressLabel;
private Label questionNumberLabel;
/**
* .
*
* @param sceneManager .
*/
public QuizView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
createScene();
}
/**
* .
*/
private void createScene() {
VBox root = new VBox(20);
root.setPadding(new Insets(30));
root.setAlignment(Pos.TOP_CENTER);
progressLabel = new Label();
progressLabel.setFont(Font.font(14));
// 创建界面组件
progressLabel = createProgressLabel();
questionNumberLabel = createQuestionNumberLabel();
questionLabel = createQuestionLabel();
optionsContainer = createOptionsContainer();
nextButton = createNextButton();
questionNumberLabel = new Label();
questionNumberLabel.setFont(Font.font(16));
questionNumberLabel.setStyle("-fx-text-fill: #666;");
root.getChildren().addAll(progressLabel, questionNumberLabel,
questionLabel, optionsContainer, nextButton);
questionLabel = new Label();
questionLabel.setFont(Font.font(18));
questionLabel.setWrapText(true);
questionLabel.setStyle("-fx-padding: 10 0 20 0;");
scene = new Scene(root, 600, 500);
}
optionsGroup = new ToggleGroup();
optionsContainer = new VBox(15);
optionsContainer.setAlignment(Pos.CENTER_LEFT);
optionsContainer.setPadding(new Insets(10));
/**
* .
*
* @return Label .
*/
private Label createProgressLabel() {
Label label = new Label();
label.setFont(Font.font(14));
return label;
}
nextButton = new Button("下一题");
nextButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 14px;");
nextButton.setPrefSize(150, 40);
nextButton.setDisable(true);
/**
* .
*
* @return Label .
*/
private Label createQuestionNumberLabel() {
Label label = new Label();
label.setFont(Font.font(16));
label.setStyle("-fx-text-fill: #666;");
return label;
}
root.getChildren().addAll(progressLabel, questionNumberLabel, questionLabel, optionsContainer, nextButton);
/**
* .
*
* @return Label .
*/
private Label createQuestionLabel() {
Label label = new Label();
label.setFont(Font.font(18));
label.setWrapText(true);
label.setStyle("-fx-padding: 10 0 20 0;");
return label;
}
scene = new Scene(root, 600, 500);
/**
* .
*
* @return VBox .
*/
private VBox createOptionsContainer() {
VBox container = new VBox(15);
container.setAlignment(Pos.CENTER_LEFT);
container.setPadding(new Insets(10));
return container;
}
/**
* .
*
* @return Button .
*/
private Button createNextButton() {
Button button = new Button("下一题");
button.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; "
+ "-fx-font-size: 14px;");
button.setPrefSize(150, 40);
button.setDisable(true);
return button;
}
/**
* .
*
* @param level .
* @param count .
*/
public void setQuizParameters(String level, int count) {
System.out.println("设置测验参数 - 级别: " + level + ", 题目数量: " + count);
@ -87,6 +156,9 @@ public class QuizView {
showQuestion(0);
}
/**
* .
*/
private void generateQuestions() {
try {
System.out.println("开始生成题目,级别: " + currentLevel + ", 数量: " + questionCount);
@ -98,20 +170,25 @@ public class QuizView {
return;
}
System.out.println("题目生成器创建成功: " + questionGenerator.getClass().getSimpleName());
System.out.println("题目生成器创建成功: "
+ questionGenerator.getClass().getSimpleName());
multipleChoiceGenerator = new MultipleChoiceGenerator(questionGenerator, currentLevel);
MultipleChoiceGenerator multipleChoiceGenerator = new MultipleChoiceGenerator(
questionGenerator, currentLevel);
questions = multipleChoiceGenerator.generateMultipleChoiceQuestions(questionCount);
System.out.println("题目生成完成,数量: " + (questions != null ? questions.size() : "null"));
System.out.println("题目生成完成,数量: "
+ (questions != null ? questions.size() : "null"));
} catch (Exception e) {
System.err.println("生成题目时出现异常: " + e.getMessage());
e.printStackTrace();
questions = java.util.Collections.emptyList();
}
}
/**
* .
*/
private void showEmptyState() {
VBox root = (VBox) scene.getRoot();
root.getChildren().clear();
@ -125,6 +202,11 @@ public class QuizView {
root.getChildren().addAll(emptyLabel, backButton);
}
/**
* .
*
* @param index .
*/
private void showQuestion(int index) {
if (index >= questions.size()) {
// 所有题目已回答,显示结果
@ -132,20 +214,49 @@ public class QuizView {
sceneManager.showResultView(score);
return;
}
QuestionWithOptions question = questions.get(index);
updateQuestionDisplay(index, question);
setupOptions(question);
setupNextButton(index, question);
}
/**
* .
*
* @param index .
* @param question .
*/
private void updateQuestionDisplay(int index, QuestionWithOptions question) {
// 更新进度和题号
progressLabel.setText("进度: " + (index + 1) + "/" + questions.size());
questionNumberLabel.setText("第 " + (index + 1) + " 题");
// 设置题目内容
String questionText = question.getQuestionText();
String questionText = formatQuestionText(question.getQuestionText());
questionLabel.setText(questionText + " = ?");
}
/**
* .
*
* @param questionText .
* @return String .
*/
private String formatQuestionText(String questionText) {
// 移除末尾的 "="
if (questionText.endsWith(" =")) {
questionText = questionText.substring(0, questionText.length() - 2);
}
questionLabel.setText(questionText + " = ?");
return questionText;
}
/**
* .
*
* @param question .
*/
private void setupOptions(QuestionWithOptions question) {
// 清空选项容器
optionsContainer.getChildren().clear();
optionsGroup = new ToggleGroup();
@ -153,15 +264,34 @@ public class QuizView {
// 添加选项
List<String> options = question.getOptions();
for (int i = 0; i < options.size(); i++) {
RadioButton radioButton = new RadioButton((char)('A' + i) + ". " + options.get(i));
radioButton.setToggleGroup(optionsGroup);
radioButton.setFont(Font.font(14));
radioButton.setWrapText(true);
radioButton.setPrefWidth(500);
RadioButton radioButton = createOptionRadioButton(i, options.get(i));
optionsContainer.getChildren().add(radioButton);
}
}
// 设置下一题按钮
/**
* .
*
* @param index .
* @param optionText .
* @return RadioButton .
*/
private RadioButton createOptionRadioButton(int index, String optionText) {
RadioButton radioButton = new RadioButton((char) ('A' + index) + ". " + optionText);
radioButton.setToggleGroup(optionsGroup);
radioButton.setFont(Font.font(14));
radioButton.setWrapText(true);
radioButton.setPrefWidth(500);
return radioButton;
}
/**
* .
*
* @param index .
* @param question .
*/
private void setupNextButton(int index, QuestionWithOptions question) {
nextButton.setDisable(true);
nextButton.setText(index == questions.size() - 1 ? "提交答案" : "下一题");
nextButton.setOnAction(e -> {
@ -170,11 +300,22 @@ public class QuizView {
});
// 启用下一题按钮当选择了一个选项时
optionsGroup.selectedToggleProperty().addListener((obs, oldVal, newVal) -> {
nextButton.setDisable(newVal == null);
});
setupOptionSelectionListener();
}
/**
* .
*/
private void setupOptionSelectionListener() {
optionsGroup.selectedToggleProperty().addListener((obs, oldVal, newVal) ->
nextButton.setDisable(newVal == null));
}
/**
* .
*
* @param question .
*/
private void checkAnswer(QuestionWithOptions question) {
RadioButton selectedRadioButton = (RadioButton) optionsGroup.getSelectedToggle();
if (selectedRadioButton != null) {
@ -185,11 +326,13 @@ public class QuizView {
}
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}
public MultipleChoiceGenerator getMultipleChoiceGenerator() {
return multipleChoiceGenerator;
}
}

@ -2,16 +2,24 @@ package com.wsf.mathapp.view;
import com.wsf.mathapp.controller.SceneManager;
import com.ybw.mathapp.util.EmailService;
import com.ybw.mathapp.util.LoginFileUtils;
import com.ybw.mathapp.util.Register;
import java.util.regex.Pattern;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import com.ybw.mathapp.util.LoginFileUtils;
/**
* .
* .
*/
public class RegisterView {
private Scene scene;
private final SceneManager sceneManager;
@ -25,178 +33,342 @@ public class RegisterView {
private Label statusLabel;
private Button sendCodeButton;
/**
* .
*
* @param sceneManager .
*/
public RegisterView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
createScene();
}
/**
* .
*/
private void createScene() {
VBox root = new VBox(15);
root.setPadding(new Insets(30));
root.setAlignment(Pos.CENTER);
// 创建界面组件
usernameField = createUsernameField();
emailField = createEmailField();
sendCodeButton = createSendCodeButton();
codeField = createCodeField();
passwordField = createPasswordField();
confirmPasswordField = createConfirmPasswordField();
Button registerButton = createRegisterButton();
statusLabel = new Label();
Button backButton = createBackButton();
// 设置按钮事件
setupSendCodeButtonAction();
setupRegisterButtonAction(registerButton);
setupBackButtonAction(backButton);
Label titleLabel = createTitleLabel();
root.getChildren().addAll(
titleLabel,
usernameField,
emailField,
sendCodeButton,
codeField,
passwordField,
confirmPasswordField,
registerButton,
backButton,
statusLabel
);
scene = new Scene(root, 400, 550);
}
/**
* .
*
* @return Label .
*/
private Label createTitleLabel() {
Label titleLabel = new Label("用户注册");
titleLabel.setFont(Font.font(20));
return titleLabel;
}
// 添加用户名输入框
usernameField = new TextField();
usernameField.setPromptText("请输入用户名(3-20位字母、数字、下划线)");
usernameField.setMaxWidth(300);
usernameField.setPrefHeight(35);
/**
* .
*
* @return TextField .
*/
private TextField createUsernameField() {
TextField field = new TextField();
field.setPromptText("请输入用户名(3-20位字母、数字、下划线)");
field.setMaxWidth(300);
field.setPrefHeight(35);
return field;
}
emailField = new TextField();
emailField.setPromptText("请输入邮箱");
emailField.setMaxWidth(300);
emailField.setPrefHeight(35);
/**
* .
*
* @return TextField .
*/
private TextField createEmailField() {
TextField field = new TextField();
field.setPromptText("请输入邮箱");
field.setMaxWidth(300);
field.setPrefHeight(35);
return field;
}
sendCodeButton = new Button("发送验证码");
sendCodeButton.setStyle("-fx-background-color: #FF9800; -fx-text-fill: white;");
sendCodeButton.setPrefSize(120, 35);
/**
* .
*
* @return Button .
*/
private Button createSendCodeButton() {
Button button = new Button("发送验证码");
button.setStyle("-fx-background-color: #FF9800; -fx-text-fill: white;");
button.setPrefSize(120, 35);
return button;
}
codeField = new TextField();
codeField.setPromptText("请输入验证码");
codeField.setMaxWidth(300);
codeField.setPrefHeight(35);
/**
* .
*
* @return TextField .
*/
private TextField createCodeField() {
TextField field = new TextField();
field.setPromptText("请输入验证码");
field.setMaxWidth(300);
field.setPrefHeight(35);
return field;
}
passwordField = new PasswordField();
passwordField.setPromptText("请输入密码(6-10位含大小写字母和数字)");
passwordField.setMaxWidth(300);
passwordField.setPrefHeight(35);
/**
* .
*
* @return PasswordField .
*/
private PasswordField createPasswordField() {
PasswordField field = new PasswordField();
field.setPromptText("请输入密码(6-10位含大小写字母和数字)");
field.setMaxWidth(300);
field.setPrefHeight(35);
return field;
}
confirmPasswordField = new PasswordField();
confirmPasswordField.setPromptText("请再次输入密码");
confirmPasswordField.setMaxWidth(300);
confirmPasswordField.setPrefHeight(35);
/**
* .
*
* @return PasswordField .
*/
private PasswordField createConfirmPasswordField() {
PasswordField field = new PasswordField();
field.setPromptText("请再次输入密码");
field.setMaxWidth(300);
field.setPrefHeight(35);
return field;
}
Button registerButton = new Button("注册");
registerButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 14px;");
registerButton.setPrefSize(300, 40);
/**
* .
*
* @return Button .
*/
private Button createRegisterButton() {
Button button = new Button("注册");
button.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; "
+ "-fx-font-size: 14px;");
button.setPrefSize(300, 40);
return button;
}
Button backButton = new Button("返回登录");
backButton.setStyle("-fx-background-color: #757575; -fx-text-fill: white;");
backButton.setPrefSize(300, 35);
/**
* .
*
* @return Button .
*/
private Button createBackButton() {
Button button = new Button("返回登录");
button.setStyle("-fx-background-color: #757575; -fx-text-fill: white;");
button.setPrefSize(300, 35);
return button;
}
statusLabel = new Label();
/**
* .
*/
private void setupSendCodeButtonAction() {
sendCodeButton.setOnAction(e -> handleSendVerificationCode());
}
sendCodeButton.setOnAction(e -> {
String username = usernameField.getText().trim();
String email = emailField.getText().trim();
/**
* .
*
* @param registerButton .
*/
private void setupRegisterButtonAction(Button registerButton) {
registerButton.setOnAction(e -> handleRegistration());
}
// 验证用户名
if (!isValidUsername(username)) {
showError(statusLabel, "用户名只包含英文字母和数字)");
return;
}
/**
* .
*
* @param backButton .
*/
private void setupBackButtonAction(Button backButton) {
backButton.setOnAction(e -> sceneManager.showLoginView());
}
// 检查用户名是否已存在
if (LoginFileUtils.isNameRegistered(username)) {
showError(statusLabel, "用户名已存在,请选择其他用户名!");
return;
}
/**
* .
*/
private void handleSendVerificationCode() {
String username = usernameField.getText().trim();
String email = emailField.getText().trim();
if (!EmailService.isValidEmail(email)) {
showError(statusLabel, "请输入有效的邮箱地址!");
return;
}
if (!validateUsernameForCode(username)) {
return;
}
if (LoginFileUtils.isEmailRegistered(email)){
showError(statusLabel, "该邮箱已注册,请直接登录!");
return;
}
if (!validateEmailForCode(email)) {
return;
}
// 生成并发送验证码
boolean sent = EmailService.sendCode(email);
if (sent) {
showSuccess(statusLabel, "验证码已发送到您的邮箱!");
// 禁用发送按钮60秒
sendCodeButton.setDisable(true);
startCountdown(sendCodeButton);
} else {
showError(statusLabel, "发送验证码失败,请稍后重试!");
}
});
registerButton.setOnAction(e -> {
String username = usernameField.getText().trim();
String email = emailField.getText().trim();
String code = codeField.getText().trim();
String password = passwordField.getText();
String confirmPassword = confirmPasswordField.getText();
// 验证用户名
if (!isValidUsername(username)) {
showError(statusLabel, "用户名只包含英文字母和数字");
return;
}
// 生成并发送验证码
boolean sent = EmailService.sendCode(email);
if (sent) {
showSuccess(statusLabel, "验证码已发送到您的邮箱!");
// 禁用发送按钮60秒
sendCodeButton.setDisable(true);
startCountdown(sendCodeButton);
} else {
showError(statusLabel, "发送验证码失败,请稍后重试!");
}
}
// 检查用户名是否已存在
if (LoginFileUtils.isNameRegistered((username))){
showError(statusLabel, "用户名已存在,请选择其他用户名!");
return;
}
/**
* .
*
* @param username .
* @return boolean .
*/
private boolean validateUsernameForCode(String username) {
if (isInvalidUsername(username)) {
showError(statusLabel, "用户名只包含英文字母和数字)");
return false;
}
if (!EmailService.isValidEmail(email)) {
showError(statusLabel, "请输入有效的邮箱地址!");
return;
}
if (LoginFileUtils.isNameRegistered(username)) {
showError(statusLabel, "用户名已存在,请选择其他用户名");
return false;
}
if (LoginFileUtils.isEmailRegistered(email)){
showError(statusLabel, "该邮箱已注册,请直接登录!");
return;
}
return true;
}
if (username.isEmpty() || email.isEmpty() || code.isEmpty() || password.isEmpty()) {
showError(statusLabel, "请填写所有字段!");
return;
}
/**
* .
*
* @param email .
* @return boolean .
*/
private boolean validateEmailForCode(String email) {
if (!EmailService.isValidEmail(email)) {
showError(statusLabel, "请输入有效的邮箱地址!");
return false;
}
// 验证验证码
if (!EmailService.verifyCode(email, code)) {
showError(statusLabel, "验证码错误或已过期!");
return;
}
if (LoginFileUtils.isEmailRegistered(email)) {
showError(statusLabel, "该邮箱已注册,请直接登录!");
return false;
}
if (!Register.isVaildPassword(password)) {
showError(statusLabel, "密码要6-10位包含大小写字母和数字");
return;
}
return true;
}
if (!Register.isEqualPassword(password,confirmPassword)){
showError(statusLabel, "两次密码不一致");
return;
}
/**
* .
*/
private void handleRegistration() {
String username = usernameField.getText().trim();
String email = emailField.getText().trim();
String code = codeField.getText().trim();
String password = passwordField.getText();
String confirmPassword = confirmPasswordField.getText();
if (!validateRegistrationInput(username, email, code, password, confirmPassword)) {
return;
}
if (Register.register(username, email, password)) {
showSuccess(statusLabel, "注册成功!用户名: " + username);
sceneManager.setCurrentUserName(username);
sceneManager.showMainMenuView();
} else {
showError(statusLabel, "注册失败,请检查信息!");
}
});
// 验证验证码
if (!EmailService.verifyCode(email, code)) {
showError(statusLabel, "验证码错误或已过期!");
return;
}
backButton.setOnAction(e -> {
sceneManager.showLoginView();
});
if (!Register.isVaildPassword(password)) {
showError(statusLabel, "密码要6-10位包含大小写字母和数字");
return;
}
root.getChildren().addAll(
titleLabel,
usernameField, // 添加用户名输入框
emailField,
sendCodeButton,
codeField,
passwordField,
confirmPasswordField,
registerButton,
backButton,
statusLabel
);
if (!Register.isEqualPassword(password, confirmPassword)) {
showError(statusLabel, "两次密码不一致");
return;
}
if (Register.register(username, email, password)) {
showSuccess(statusLabel, "注册成功!用户名: " + username);
sceneManager.setCurrentUserName(username);
sceneManager.showMainMenuView();
} else {
showError(statusLabel, "注册失败,请检查信息!");
}
}
/**
* .
*
* @param username .
* @param email .
* @param code .
* @param password .
* @param confirmPassword .
* @return boolean .
*/
private boolean validateRegistrationInput(String username, String email,
String code, String password, String confirmPassword) {
if (isInvalidUsername(username)) {
showError(statusLabel, "用户名只包含英文字母和数字");
return false;
}
scene = new Scene(root, 400, 550); // 增加高度以适应新字段
if (LoginFileUtils.isNameRegistered(username)) {
showError(statusLabel, "用户名已存在,请选择其他用户名!");
return false;
}
if (!EmailService.isValidEmail(email)) {
showError(statusLabel, "请输入有效的邮箱地址!");
return false;
}
if (LoginFileUtils.isEmailRegistered(email)) {
showError(statusLabel, "该邮箱已注册,请直接登录!");
return false;
}
if (username.isEmpty() || email.isEmpty() || code.isEmpty()
|| password.isEmpty() || confirmPassword.isEmpty()) {
showError(statusLabel, "请填写所有字段!");
return false;
}
return true;
}
/**
*
* .
*/
public void clearFields() {
usernameField.clear();
@ -211,14 +383,17 @@ public class RegisterView {
sendCodeButton.setDisable(false);
}
/**
* .
*
* @param button .
*/
private void startCountdown(Button button) {
new Thread(() -> {
try {
for (int i = 60; i > 0; i--) {
int finalI = i;
javafx.application.Platform.runLater(() -> {
button.setText(finalI + "秒后重发");
});
javafx.application.Platform.runLater(() -> button.setText(finalI + "秒后重发"));
Thread.sleep(1000);
}
javafx.application.Platform.runLater(() -> {
@ -226,31 +401,54 @@ public class RegisterView {
button.setDisable(false);
});
} catch (InterruptedException ex) {
ex.printStackTrace();
// ex.printStackTrace();
}
}).start();
}
/**
* .
*
* @param label .
* @param message .
*/
private void showError(Label label, String message) {
label.setText(message);
label.setStyle("-fx-text-fill: red;");
}
/**
* .
*
* @param label .
* @param message .
*/
private void showSuccess(Label label, String message) {
label.setText(message);
label.setStyle("-fx-text-fill: green;");
}
public Scene getScene() {
return scene;
}
public static boolean isValidUsername(String username) {
/**
* .
*
* @param username .
* @return boolean .
*/
public static boolean isInvalidUsername(String username) {
if (username == null || username.trim().isEmpty()) {
return false;
return true;
}
// 用户名规则:只包含英文字母和数字,不限制长度
String usernameRegex = "^[a-zA-Z0-9]+$";
return Pattern.matches(usernameRegex, username.trim());
return !Pattern.matches(usernameRegex, username.trim());
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}
}

@ -1,32 +1,37 @@
package com.wsf.mathapp.view;
import com.wsf.mathapp.controller.SceneManager;
import java.util.Objects;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
/**
* .
* .
*/
public class ResultView {
private Scene scene;
private final SceneManager sceneManager;
private double score;
private String currentUsername;
/**
* .
*
* @param sceneManager .
*/
public ResultView(SceneManager sceneManager) {
this.sceneManager = sceneManager;
this.currentUsername = sceneManager.getCurrentUserName();
createScene();
}
/**
* .
*/
private void createScene() {
// 创建主容器
VBox mainContainer = new VBox();
@ -40,9 +45,14 @@ public class ResultView {
mainContainer.getChildren().addAll(userInfoBar, resultContent);
scene = new Scene(mainContainer, 500, 550); // 增加宽度和高度以适应新布局
scene = new Scene(mainContainer, 500, 550);
}
/**
* .
*
* @return HBox .
*/
private HBox createUserInfoBar() {
HBox userInfoBar = new HBox(10);
userInfoBar.setAlignment(Pos.CENTER_LEFT);
@ -50,13 +60,49 @@ public class ResultView {
return userInfoBar;
}
/**
* .
*
* @return VBox .
*/
private VBox createResultContent() {
VBox resultContent = new VBox(30);
resultContent.setPadding(new Insets(20));
resultContent.setAlignment(Pos.CENTER);
// 创建标题区域
Label titleLabel = createTitleLabel();
// 创建分数显示区域
VBox scoreSection = createScoreSection();
// 创建按钮区域
VBox buttonSection = createButtonSection();
resultContent.getChildren().addAll(titleLabel, scoreSection, buttonSection);
return resultContent;
}
/**
* .
*
* @return Label .
*/
private Label createTitleLabel() {
Label titleLabel = new Label("答题完成");
titleLabel.setFont(Font.font(24));
return titleLabel;
}
/**
* .
*
* @return VBox .
*/
private VBox createScoreSection() {
VBox scoreSection = new VBox(15);
scoreSection.setAlignment(Pos.CENTER);
Label scoreLabel = new Label();
scoreLabel.setFont(Font.font(48));
@ -64,73 +110,169 @@ public class ResultView {
Label messageLabel = new Label();
messageLabel.setFont(Font.font(18));
Button restartButton = new Button("再次练习");
restartButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 16px;");
restartButton.setPrefSize(200, 50);
scoreSection.getChildren().addAll(scoreLabel, messageLabel);
return scoreSection;
}
Button mainMenuButton = new Button("返回主菜单");
mainMenuButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 16px;");
mainMenuButton.setPrefSize(200, 50);
/**
* .
*
* @return VBox .
*/
private VBox createButtonSection() {
VBox buttonSection = new VBox(15);
buttonSection.setAlignment(Pos.CENTER);
Button exitButton = new Button("退出系统");
exitButton.setStyle("-fx-background-color: #757575; -fx-text-fill: white; -fx-font-size: 16px;");
exitButton.setPrefSize(200, 50);
Button restartButton = createRestartButton();
Button mainMenuButton = createMainMenuButton();
Button exitButton = createExitButton();
restartButton.setOnAction(e -> {
sceneManager.showLevelSelectionView();
});
setupButtonActions(restartButton, mainMenuButton, exitButton);
mainMenuButton.setOnAction(e -> {
sceneManager.showMainMenuView();
});
buttonSection.getChildren().addAll(restartButton, mainMenuButton, exitButton);
return buttonSection;
}
exitButton.setOnAction(e -> {
System.exit(0);
});
/**
* .
*
* @return Button .
*/
private Button createRestartButton() {
Button button = new Button("再次练习");
button.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; "
+ "-fx-font-size: 16px;");
button.setPrefSize(200, 50);
return button;
}
resultContent.getChildren().addAll(
titleLabel, scoreLabel, messageLabel,
restartButton, mainMenuButton, exitButton
);
/**
* .
*
* @return Button .
*/
private Button createMainMenuButton() {
Button button = new Button("返回主菜单");
button.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; "
+ "-fx-font-size: 16px;");
button.setPrefSize(200, 50);
return button;
}
return resultContent;
/**
* 退.
*
* @return Button 退.
*/
private Button createExitButton() {
Button button = new Button("退出系统");
button.setStyle("-fx-background-color: #757575; -fx-text-fill: white; "
+ "-fx-font-size: 16px;");
button.setPrefSize(200, 50);
return button;
}
/**
* .
*
* @param restartButton .
* @param mainMenuButton .
* @param exitButton 退.
*/
private void setupButtonActions(Button restartButton, Button mainMenuButton,
Button exitButton) {
restartButton.setOnAction(e -> sceneManager.showLevelSelectionView());
mainMenuButton.setOnAction(e -> sceneManager.showMainMenuView());
exitButton.setOnAction(e -> System.exit(0));
}
/**
* .
*
* @param score 0-1.
*/
public void setScore(double score) {
this.score = score;
updateScoreDisplay();
}
/**
* .
*/
private void updateScoreDisplay() {
if (scene != null) {
VBox mainContainer = (VBox) scene.getRoot();
VBox resultContent = (VBox) mainContainer.getChildren().get(1);
Label scoreLabel = (Label) resultContent.getChildren().get(1);
Label messageLabel = (Label) resultContent.getChildren().get(2);
int percentage = (int) (score * 100);
scoreLabel.setText(percentage + "分");
// 根据分数设置不同的颜色和评语
if (score >= 0.9) {
scoreLabel.setStyle("-fx-text-fill: #4CAF50;");
messageLabel.setText("优秀!表现非常出色!");
} else if (score >= 0.7) {
scoreLabel.setStyle("-fx-text-fill: #FF9800;");
messageLabel.setText("良好!继续加油!");
} else if (score >= 0.6) {
scoreLabel.setStyle("-fx-text-fill: #FFC107;");
messageLabel.setText("及格!还有进步空间!");
} else {
scoreLabel.setStyle("-fx-text-fill: #f44336;");
messageLabel.setText("需要多加练习!");
}
VBox scoreSection = (VBox) resultContent.getChildren().get(1);
Label scoreLabel = (Label) scoreSection.getChildren().get(0);
Label messageLabel = (Label) scoreSection.getChildren().get(1);
updateScoreLabel(scoreLabel);
updateMessageLabel(messageLabel);
}
}
/**
* .
*
* @param scoreLabel .
*/
private void updateScoreLabel(Label scoreLabel) {
int percentage = (int) (score * 100);
scoreLabel.setText(percentage + "分");
applyScoreColor(scoreLabel);
}
/**
* .
*
* @param messageLabel .
*/
private void updateMessageLabel(Label messageLabel) {
messageLabel.setText(getScoreMessage());
}
/**
* .
*
* @param scoreLabel .
*/
private void applyScoreColor(Label scoreLabel) {
if (score >= 0.9) {
scoreLabel.setStyle("-fx-text-fill: #4CAF50;");
} else if (score >= 0.7) {
scoreLabel.setStyle("-fx-text-fill: #FF9800;");
} else if (score >= 0.6) {
scoreLabel.setStyle("-fx-text-fill: #FFC107;");
} else {
scoreLabel.setStyle("-fx-text-fill: #f44336;");
}
}
/**
* .
*
* @return String .
*/
private String getScoreMessage() {
if (score >= 0.9) {
return "优秀!表现非常出色!";
} else if (score >= 0.7) {
return "良好!继续加油!";
} else if (score >= 0.6) {
return "及格!还有进步空间!";
} else {
return "需要多加练习!";
}
}
/**
* .
*
* @return Scene .
*/
public Scene getScene() {
return scene;
}
}
Loading…
Cancel
Save