|
|
|
|
@ -1,952 +0,0 @@
|
|
|
|
|
import javax.swing.*;
|
|
|
|
|
import java.awt.*;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
public class MathLearningApp {
|
|
|
|
|
private JFrame mainFrame;
|
|
|
|
|
private UserManager userManager;
|
|
|
|
|
private QuizController quizController;
|
|
|
|
|
|
|
|
|
|
// 使用新的数据模型
|
|
|
|
|
private ViewData viewData;
|
|
|
|
|
private AppController appController;
|
|
|
|
|
private ViewBuilder viewBuilder;
|
|
|
|
|
private EventHandlers eventHandlers;
|
|
|
|
|
|
|
|
|
|
private static final String SYSTEM_EMAIL_HOST = "smtp.qq.com";
|
|
|
|
|
private static final String SYSTEM_EMAIL_PORT = "587";
|
|
|
|
|
private static final String SYSTEM_EMAIL_USERNAME = "2747764757@qq.com";
|
|
|
|
|
private static final String SYSTEM_EMAIL_PASSWORD = "dkagkfnxoxgxdcjj";
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
new MathLearningApp().createAndShowGUI();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createAndShowGUI() {
|
|
|
|
|
try {
|
|
|
|
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mainFrame = new JFrame("中小学数学学习软件");
|
|
|
|
|
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
|
mainFrame.setSize(500, 550);
|
|
|
|
|
mainFrame.setLocationRelativeTo(null);
|
|
|
|
|
|
|
|
|
|
// 初始化MVC组件
|
|
|
|
|
initializeMVCComponents();
|
|
|
|
|
|
|
|
|
|
showLoginView();
|
|
|
|
|
mainFrame.setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeMVCComponents() {
|
|
|
|
|
userManager = new UserManager(SYSTEM_EMAIL_HOST, SYSTEM_EMAIL_PORT,
|
|
|
|
|
SYSTEM_EMAIL_USERNAME, SYSTEM_EMAIL_PASSWORD);
|
|
|
|
|
quizController = new QuizController();
|
|
|
|
|
|
|
|
|
|
viewData = new ViewData();
|
|
|
|
|
appController = new AppController();
|
|
|
|
|
viewBuilder = new ViewBuilder();
|
|
|
|
|
eventHandlers = new EventHandlers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 重构后的界面方法 ====================
|
|
|
|
|
|
|
|
|
|
private void showLoginView() {
|
|
|
|
|
JPanel loginPanel = viewBuilder.buildLoginView((email, password) -> {
|
|
|
|
|
if (appController.handleLogin(email, password)) {
|
|
|
|
|
showMainView();
|
|
|
|
|
} else {
|
|
|
|
|
// 错误处理可以在ViewBuilder中处理
|
|
|
|
|
JOptionPane.showMessageDialog(mainFrame, "登录失败,请检查邮箱和密码!", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
}, () -> showRegisterView());
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(loginPanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showRegisterView() {
|
|
|
|
|
JPanel registerPanel = viewBuilder.buildRegisterView(
|
|
|
|
|
(username, email) -> appController.handleSendVerificationCode(username, email),
|
|
|
|
|
(username, email, code, password, confirmPassword) ->
|
|
|
|
|
appController.handleRegister(username, email, code, password, confirmPassword),
|
|
|
|
|
() -> showLoginView()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(registerPanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showMainView() {
|
|
|
|
|
JPanel mainPanel = viewBuilder.buildMainView(
|
|
|
|
|
(difficulty) -> showQuestionCountView(difficulty),
|
|
|
|
|
() -> showChangePasswordView(),
|
|
|
|
|
() -> appController.handleLogout()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(mainPanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showQuestionCountView(String difficulty) {
|
|
|
|
|
JPanel countPanel = viewBuilder.buildQuestionCountView(difficulty,
|
|
|
|
|
(count) -> {
|
|
|
|
|
if (appController.handleStartQuiz(difficulty, count)) {
|
|
|
|
|
showQuizView();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(mainFrame, "题目数量必须在10-30之间!", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
() -> showMainView()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(countPanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showQuizView() {
|
|
|
|
|
QuizController.Question currentQuestion = quizController.getCurrentQuestion();
|
|
|
|
|
if (currentQuestion == null) {
|
|
|
|
|
showScoreView();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JPanel quizPanel = viewBuilder.buildQuizView(
|
|
|
|
|
quizController.getCurrentQuestionNumber(),
|
|
|
|
|
quizController.getTotalQuestions(),
|
|
|
|
|
currentQuestion,
|
|
|
|
|
(selectedAnswer) -> {
|
|
|
|
|
appController.handleAnswerSubmit(selectedAnswer);
|
|
|
|
|
if (quizController.hasNextQuestion()) {
|
|
|
|
|
quizController.nextQuestion();
|
|
|
|
|
showQuizView(); // 刷新界面显示下一题
|
|
|
|
|
} else {
|
|
|
|
|
showScoreView();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(quizPanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
mainFrame.setSize(550, 500);
|
|
|
|
|
mainFrame.setLocationRelativeTo(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showScoreView() {
|
|
|
|
|
int score = quizController.getScore();
|
|
|
|
|
int total = quizController.getTotalQuestions();
|
|
|
|
|
double percentage = quizController.getPercentage();
|
|
|
|
|
|
|
|
|
|
JPanel scorePanel = viewBuilder.buildScoreView(score, total, percentage,
|
|
|
|
|
() -> showMainView()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(scorePanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void showChangePasswordView() {
|
|
|
|
|
JPanel changePasswordPanel = viewBuilder.buildChangePasswordView(
|
|
|
|
|
(oldPassword, newPassword, confirmPassword) ->
|
|
|
|
|
appController.handleChangePassword(oldPassword, newPassword, confirmPassword),
|
|
|
|
|
() -> showMainView()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
mainFrame.setContentPane(changePasswordPanel);
|
|
|
|
|
mainFrame.revalidate();
|
|
|
|
|
mainFrame.repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isValidEmail(String email) {
|
|
|
|
|
String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
|
|
|
|
|
return email != null && email.matches(emailRegex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =========================================================================
|
|
|
|
|
// MVC 架构内部类
|
|
|
|
|
// =========================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 数据模型 - 负责管理视图数据
|
|
|
|
|
*/
|
|
|
|
|
private class ViewData {
|
|
|
|
|
private UserManager.User currentUser;
|
|
|
|
|
private String currentMessage;
|
|
|
|
|
private Color messageColor;
|
|
|
|
|
|
|
|
|
|
public UserManager.User getCurrentUser() {
|
|
|
|
|
return currentUser;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setCurrentUser(UserManager.User user) {
|
|
|
|
|
this.currentUser = user;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getCurrentMessage() {
|
|
|
|
|
return currentMessage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setCurrentMessage(String message, Color color) {
|
|
|
|
|
this.currentMessage = message;
|
|
|
|
|
this.messageColor = color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Color getMessageColor() {
|
|
|
|
|
return messageColor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用控制器 - 处理所有业务逻辑
|
|
|
|
|
*/
|
|
|
|
|
private class AppController {
|
|
|
|
|
public boolean handleLogin(String email, String password) {
|
|
|
|
|
if (userManager.login(email, password)) {
|
|
|
|
|
viewData.setCurrentUser(userManager.getCurrentUser());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean handleSendVerificationCode(String username, String email) {
|
|
|
|
|
if (username.isEmpty() || email.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (userManager.isUsernameExists(username)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (userManager.isUserExists(email)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String code = userManager.generateAndSendVerificationCode(email);
|
|
|
|
|
return code != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean handleRegister(String username, String email, String code,
|
|
|
|
|
String password, String confirmPassword) {
|
|
|
|
|
if (!password.equals(confirmPassword)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!userManager.isValidPassword(password)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return userManager.registerUser(username, email, code, password);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean handleStartQuiz(String difficulty, int count) {
|
|
|
|
|
if (count >= 10 && count <= 30) {
|
|
|
|
|
quizController.startNewQuiz(difficulty, count);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handleAnswerSubmit(int selectedAnswer) {
|
|
|
|
|
quizController.submitAnswer(selectedAnswer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean handleChangePassword(String oldPassword, String newPassword, String confirmPassword) {
|
|
|
|
|
if (!newPassword.equals(confirmPassword)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!userManager.isValidPassword(newPassword)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return userManager.changePassword(oldPassword, newPassword);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handleLogout() {
|
|
|
|
|
userManager.logout();
|
|
|
|
|
viewData.setCurrentUser(null);
|
|
|
|
|
showLoginView();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 视图构建器 - 负责构建所有界面组件
|
|
|
|
|
*/
|
|
|
|
|
private class ViewBuilder {
|
|
|
|
|
public JPanel buildLoginView(LoginListener loginListener, Runnable backToLogin) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
JLabel titleLabel = new JLabel("数学学习软件 - 登录");
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
|
|
|
|
|
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
// 输入面板
|
|
|
|
|
JPanel inputPanel = new JPanel();
|
|
|
|
|
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
|
|
|
|
|
inputPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JTextField emailField = new JTextField(20);
|
|
|
|
|
emailField.setPreferredSize(new Dimension(200, 30));
|
|
|
|
|
|
|
|
|
|
JPasswordField passwordField = new JPasswordField(20);
|
|
|
|
|
passwordField.setPreferredSize(new Dimension(200, 30));
|
|
|
|
|
|
|
|
|
|
JPanel emailPanel = createLabelFieldPanel("邮箱:", emailField);
|
|
|
|
|
JPanel passwordPanel = createLabelFieldPanel("密码:", passwordField);
|
|
|
|
|
|
|
|
|
|
inputPanel.add(emailPanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(passwordPanel);
|
|
|
|
|
|
|
|
|
|
// 按钮面板
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new FlowLayout());
|
|
|
|
|
buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JButton loginButton = createStyledButton("登录", new Color(76, 175, 80), 120, 35);
|
|
|
|
|
JButton registerButton = createStyledButton("前往注册", new Color(33, 150, 243), 120, 35);
|
|
|
|
|
|
|
|
|
|
loginButton.addActionListener(e -> {
|
|
|
|
|
String email = emailField.getText();
|
|
|
|
|
String password = new String(passwordField.getPassword());
|
|
|
|
|
loginListener.onLogin(email, password);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
registerButton.addActionListener(e -> backToLogin.run());
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(loginButton);
|
|
|
|
|
buttonPanel.add(Box.createHorizontalStrut(20));
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
|
|
|
|
|
// 组装主面板
|
|
|
|
|
panel.add(Box.createVerticalStrut(20));
|
|
|
|
|
panel.add(titleLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(30));
|
|
|
|
|
panel.add(inputPanel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(30));
|
|
|
|
|
panel.add(buttonPanel);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JPanel buildRegisterView(SendCodeListener sendCodeListener, RegisterListener registerListener, Runnable backAction) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
|
|
|
|
|
|
|
|
|
|
JLabel titleLabel = new JLabel("用户注册");
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
|
|
|
|
|
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JPanel inputPanel = new JPanel();
|
|
|
|
|
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
|
|
|
|
|
inputPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JTextField usernameField = new JTextField(20);
|
|
|
|
|
JTextField emailField = new JTextField(20);
|
|
|
|
|
JTextField codeField = new JTextField(15);
|
|
|
|
|
JPasswordField passwordField = new JPasswordField(20);
|
|
|
|
|
JPasswordField confirmPasswordField = new JPasswordField(20);
|
|
|
|
|
|
|
|
|
|
// 初始禁用状态
|
|
|
|
|
codeField.setEnabled(false);
|
|
|
|
|
passwordField.setEnabled(false);
|
|
|
|
|
confirmPasswordField.setEnabled(false);
|
|
|
|
|
|
|
|
|
|
JButton sendCodeButton = createStyledButton("发送验证码", new Color(255, 152, 0), 120, 30);
|
|
|
|
|
JButton registerButton = createStyledButton("注册", new Color(76, 175, 80), 120, 35);
|
|
|
|
|
registerButton.setEnabled(false); // 初始禁用注册按钮
|
|
|
|
|
JButton backButton = createStyledButton("返回登录", new Color(158, 158, 158), 120, 35);
|
|
|
|
|
|
|
|
|
|
// 添加消息标签
|
|
|
|
|
JLabel messageLabel = new JLabel(" ");
|
|
|
|
|
messageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
|
|
|
|
|
// 构建各个输入行
|
|
|
|
|
JPanel usernamePanel = createLabelFieldPanel("用户名:", usernameField);
|
|
|
|
|
JPanel emailPanel = createLabelFieldPanel("邮箱:", emailField);
|
|
|
|
|
|
|
|
|
|
JPanel codePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
|
|
|
|
codePanel.add(new JLabel("验证码:"));
|
|
|
|
|
codePanel.add(codeField);
|
|
|
|
|
codePanel.add(Box.createHorizontalStrut(10));
|
|
|
|
|
codePanel.add(sendCodeButton);
|
|
|
|
|
|
|
|
|
|
JPanel passwordPanel = createLabelFieldPanel("密码:", passwordField);
|
|
|
|
|
JPanel confirmPasswordPanel = createLabelFieldPanel("确认密码:", confirmPasswordField);
|
|
|
|
|
|
|
|
|
|
inputPanel.add(usernamePanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(emailPanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(codePanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(passwordPanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(confirmPasswordPanel);
|
|
|
|
|
|
|
|
|
|
// 按钮面板
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new FlowLayout());
|
|
|
|
|
buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
buttonPanel.add(Box.createHorizontalStrut(20));
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
// 发送验证码事件处理
|
|
|
|
|
sendCodeButton.addActionListener(e -> {
|
|
|
|
|
String username = usernameField.getText().trim();
|
|
|
|
|
String email = emailField.getText().trim();
|
|
|
|
|
|
|
|
|
|
// 客户端验证
|
|
|
|
|
if (username.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请输入用户名!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (email.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请输入邮箱地址!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isValidEmail(email)) {
|
|
|
|
|
messageLabel.setText("邮箱格式错误!请输入有效的邮箱地址。");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查用户名是否已存在
|
|
|
|
|
if (userManager.isUsernameExists(username)) {
|
|
|
|
|
messageLabel.setText("用户名已存在,请选择其他用户名!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查邮箱是否已被注册
|
|
|
|
|
if (userManager.isUserExists(email)) {
|
|
|
|
|
messageLabel.setText("该邮箱已被注册,请使用其他邮箱!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 禁用发送按钮,显示发送中状态
|
|
|
|
|
sendCodeButton.setEnabled(false);
|
|
|
|
|
sendCodeButton.setText("发送中...");
|
|
|
|
|
messageLabel.setText("正在发送验证码,请稍候...");
|
|
|
|
|
messageLabel.setForeground(Color.BLUE);
|
|
|
|
|
|
|
|
|
|
// 在新线程中发送验证码,避免阻塞UI
|
|
|
|
|
new Thread(() -> {
|
|
|
|
|
boolean success = sendCodeListener.onSendCode(username, email);
|
|
|
|
|
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
if (success) {
|
|
|
|
|
messageLabel.setText("<html>验证码已发送到您的邮箱: " + email + "<br>请查看邮件并输入验证码</html>");
|
|
|
|
|
messageLabel.setForeground(Color.GREEN);
|
|
|
|
|
|
|
|
|
|
// 启用相关输入框
|
|
|
|
|
codeField.setEnabled(true);
|
|
|
|
|
passwordField.setEnabled(true);
|
|
|
|
|
confirmPasswordField.setEnabled(true);
|
|
|
|
|
registerButton.setEnabled(true);
|
|
|
|
|
} else {
|
|
|
|
|
messageLabel.setText("验证码发送失败,请检查邮箱地址或稍后重试!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 恢复发送按钮状态
|
|
|
|
|
sendCodeButton.setEnabled(true);
|
|
|
|
|
sendCodeButton.setText("发送验证码");
|
|
|
|
|
});
|
|
|
|
|
}).start();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 注册事件处理
|
|
|
|
|
registerButton.addActionListener(e -> {
|
|
|
|
|
String username = usernameField.getText().trim();
|
|
|
|
|
String email = emailField.getText().trim();
|
|
|
|
|
String code = codeField.getText().trim();
|
|
|
|
|
String password = new String(passwordField.getPassword());
|
|
|
|
|
String confirmPassword = new String(confirmPasswordField.getPassword());
|
|
|
|
|
|
|
|
|
|
// 客户端验证
|
|
|
|
|
if (username.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请输入用户名!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (email.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请输入邮箱地址!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (code.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请输入验证码!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (password.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请输入密码!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!password.equals(confirmPassword)) {
|
|
|
|
|
messageLabel.setText("两次输入的密码不一致!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!userManager.isValidPassword(password)) {
|
|
|
|
|
messageLabel.setText("<html>密码不符合要求:<br>- 长度必须在6-10位之间<br>- 必须包含大写字母、小写字母和数字</html>");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用注册逻辑
|
|
|
|
|
boolean success = registerListener.onRegister(username, email, code, password, confirmPassword);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
messageLabel.setText("注册成功!请返回登录");
|
|
|
|
|
messageLabel.setForeground(Color.GREEN);
|
|
|
|
|
registerButton.setEnabled(false);
|
|
|
|
|
sendCodeButton.setEnabled(false);
|
|
|
|
|
} else {
|
|
|
|
|
messageLabel.setText("<html>注册失败!请检查:<br>- 验证码是否正确<br>- 密码是否符合要求<br>- 邮箱或用户名是否已注册</html>");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
backButton.addActionListener(e -> backAction.run());
|
|
|
|
|
|
|
|
|
|
// 组装主面板
|
|
|
|
|
panel.add(Box.createVerticalStrut(10));
|
|
|
|
|
panel.add(titleLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(25));
|
|
|
|
|
panel.add(inputPanel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(15));
|
|
|
|
|
panel.add(messageLabel); // 添加消息标签
|
|
|
|
|
panel.add(Box.createVerticalStrut(10));
|
|
|
|
|
panel.add(buttonPanel);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JPanel buildMainView(DifficultySelectListener difficultyListener,
|
|
|
|
|
Runnable changePasswordAction, Runnable logoutAction) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 40, 40));
|
|
|
|
|
|
|
|
|
|
String welcomeText = viewData.getCurrentUser() != null ?
|
|
|
|
|
"欢迎 " + viewData.getCurrentUser().getUsername() + " 使用数学学习软件!" :
|
|
|
|
|
"欢迎使用数学学习软件!";
|
|
|
|
|
|
|
|
|
|
JLabel welcomeLabel = new JLabel(welcomeText);
|
|
|
|
|
welcomeLabel.setFont(new Font("微软雅黑", Font.BOLD, 22));
|
|
|
|
|
welcomeLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JLabel instructionLabel = new JLabel("请选择题目难度:");
|
|
|
|
|
instructionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
|
|
|
|
|
instructionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
// 难度按钮面板
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
|
|
|
|
|
buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JButton primaryBtn = createDifficultyButton("小学", new Color(76, 175, 80));
|
|
|
|
|
JButton middleBtn = createDifficultyButton("初中", new Color(33, 150, 243));
|
|
|
|
|
JButton highBtn = createDifficultyButton("高中", new Color(255, 152, 0));
|
|
|
|
|
|
|
|
|
|
primaryBtn.addActionListener(e -> difficultyListener.onDifficultySelected("小学"));
|
|
|
|
|
middleBtn.addActionListener(e -> difficultyListener.onDifficultySelected("初中"));
|
|
|
|
|
highBtn.addActionListener(e -> difficultyListener.onDifficultySelected("高中"));
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(primaryBtn);
|
|
|
|
|
buttonPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
buttonPanel.add(middleBtn);
|
|
|
|
|
buttonPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
buttonPanel.add(highBtn);
|
|
|
|
|
|
|
|
|
|
// 功能按钮面板
|
|
|
|
|
JPanel functionPanel = new JPanel();
|
|
|
|
|
functionPanel.setLayout(new FlowLayout());
|
|
|
|
|
functionPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JButton changePasswordBtn = createStyledButton("修改密码", new Color(96, 125, 139), 120, 35);
|
|
|
|
|
JButton logoutBtn = createStyledButton("退出登录", new Color(244, 67, 54), 120, 35);
|
|
|
|
|
|
|
|
|
|
changePasswordBtn.addActionListener(e -> changePasswordAction.run());
|
|
|
|
|
logoutBtn.addActionListener(e -> logoutAction.run());
|
|
|
|
|
|
|
|
|
|
functionPanel.add(changePasswordBtn);
|
|
|
|
|
functionPanel.add(Box.createHorizontalStrut(20));
|
|
|
|
|
functionPanel.add(logoutBtn);
|
|
|
|
|
|
|
|
|
|
// 组装主面板
|
|
|
|
|
panel.add(Box.createVerticalStrut(20));
|
|
|
|
|
panel.add(welcomeLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(10));
|
|
|
|
|
panel.add(instructionLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(30));
|
|
|
|
|
panel.add(buttonPanel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(30));
|
|
|
|
|
panel.add(functionPanel);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JPanel buildQuestionCountView(String difficulty, CountSubmitListener countListener, Runnable backAction) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 40, 40));
|
|
|
|
|
|
|
|
|
|
JLabel titleLabel = new JLabel("准备生成" + difficulty + "数学题目");
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
|
|
|
|
|
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JLabel instructionLabel = new JLabel("请输入题目数量 (10-30):");
|
|
|
|
|
instructionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
instructionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JPanel inputPanel = new JPanel();
|
|
|
|
|
inputPanel.setLayout(new FlowLayout());
|
|
|
|
|
inputPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JTextField countField = new JTextField(10);
|
|
|
|
|
countField.setPreferredSize(new Dimension(100, 30));
|
|
|
|
|
inputPanel.add(countField);
|
|
|
|
|
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new FlowLayout());
|
|
|
|
|
buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JButton startButton = createStyledButton("开始答题", new Color(76, 175, 80), 120, 35);
|
|
|
|
|
JButton backButton = createStyledButton("返回", new Color(158, 158, 158), 120, 35);
|
|
|
|
|
|
|
|
|
|
startButton.addActionListener(e -> {
|
|
|
|
|
try {
|
|
|
|
|
int count = Integer.parseInt(countField.getText());
|
|
|
|
|
countListener.onCountSubmit(count);
|
|
|
|
|
} catch (NumberFormatException ex) {
|
|
|
|
|
JOptionPane.showMessageDialog(mainFrame, "请输入有效的数字!", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
backButton.addActionListener(e -> backAction.run());
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(startButton);
|
|
|
|
|
buttonPanel.add(Box.createHorizontalStrut(20));
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
panel.add(Box.createVerticalStrut(20));
|
|
|
|
|
panel.add(titleLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(20));
|
|
|
|
|
panel.add(instructionLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(15));
|
|
|
|
|
panel.add(inputPanel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(25));
|
|
|
|
|
panel.add(buttonPanel);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JPanel buildQuizView(int currentNumber, int totalQuestions, QuizController.Question question, AnswerSubmitListener answerListener) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BorderLayout());
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
|
|
|
|
|
|
|
|
|
|
// 信息面板
|
|
|
|
|
JPanel infoPanel = new JPanel();
|
|
|
|
|
infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.Y_AXIS));
|
|
|
|
|
infoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10));
|
|
|
|
|
|
|
|
|
|
JLabel questionNumberLabel = new JLabel("第 " + currentNumber + " 题 / 共 " + totalQuestions + " 题");
|
|
|
|
|
questionNumberLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
|
|
|
|
|
|
|
|
|
|
JLabel questionContentLabel = new JLabel("<html>" + question.getContent() + "</html>");
|
|
|
|
|
questionContentLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
|
|
|
|
|
questionContentLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
|
|
|
|
|
|
|
|
|
|
infoPanel.add(questionNumberLabel);
|
|
|
|
|
infoPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
infoPanel.add(questionContentLabel);
|
|
|
|
|
|
|
|
|
|
// 选项面板
|
|
|
|
|
JPanel optionsPanel = new JPanel();
|
|
|
|
|
optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.Y_AXIS));
|
|
|
|
|
optionsPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
|
|
|
|
|
|
|
|
|
|
ButtonGroup answerGroup = new ButtonGroup();
|
|
|
|
|
JRadioButton[] optionButtons = new JRadioButton[4];
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
optionButtons[i] = new JRadioButton((char) ('A' + i) + ". " + question.getOptions()[i]);
|
|
|
|
|
optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
optionButtons[i].setActionCommand(String.valueOf(i));
|
|
|
|
|
answerGroup.add(optionButtons[i]);
|
|
|
|
|
optionsPanel.add(optionButtons[i]);
|
|
|
|
|
optionsPanel.add(Box.createVerticalStrut(12));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提交按钮
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new FlowLayout());
|
|
|
|
|
buttonPanel.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 10));
|
|
|
|
|
|
|
|
|
|
JButton submitButton = createStyledButton("提交答案", new Color(76, 175, 80), 140, 40);
|
|
|
|
|
submitButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
|
|
|
|
|
|
|
|
|
|
submitButton.addActionListener(e -> {
|
|
|
|
|
ButtonModel selectedModel = answerGroup.getSelection();
|
|
|
|
|
if (selectedModel == null) {
|
|
|
|
|
JOptionPane.showMessageDialog(mainFrame, "请选择一个答案!", "提示", JOptionPane.WARNING_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int selectedIndex = Integer.parseInt(selectedModel.getActionCommand());
|
|
|
|
|
answerListener.onAnswerSubmit(selectedIndex);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(submitButton);
|
|
|
|
|
|
|
|
|
|
JScrollPane scrollPane = new JScrollPane(optionsPanel);
|
|
|
|
|
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
|
|
|
|
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
|
|
|
|
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
|
|
|
|
|
|
|
|
|
panel.add(infoPanel, BorderLayout.NORTH);
|
|
|
|
|
panel.add(scrollPane, BorderLayout.CENTER);
|
|
|
|
|
panel.add(buttonPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JPanel buildScoreView(int score, int total, double percentage, Runnable continueAction) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 40, 40));
|
|
|
|
|
|
|
|
|
|
JLabel titleLabel = new JLabel("答题完成!");
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
|
|
|
|
|
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JLabel scoreLabel = new JLabel("得分: " + score + "/" + total);
|
|
|
|
|
scoreLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18));
|
|
|
|
|
scoreLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JLabel percentageLabel = new JLabel("正确率: " + String.format("%.1f", percentage) + "%");
|
|
|
|
|
percentageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
|
|
|
|
|
percentageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
if (percentage >= 80) {
|
|
|
|
|
percentageLabel.setForeground(new Color(76, 175, 80));
|
|
|
|
|
} else if (percentage >= 60) {
|
|
|
|
|
percentageLabel.setForeground(new Color(255, 152, 0));
|
|
|
|
|
} else {
|
|
|
|
|
percentageLabel.setForeground(new Color(244, 67, 54));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new FlowLayout());
|
|
|
|
|
buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JButton continueButton = createStyledButton("继续做题", new Color(76, 175, 80), 120, 35);
|
|
|
|
|
|
|
|
|
|
continueButton.addActionListener(e -> continueAction.run());
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(continueButton);
|
|
|
|
|
|
|
|
|
|
panel.add(Box.createVerticalStrut(20));
|
|
|
|
|
panel.add(titleLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(30));
|
|
|
|
|
panel.add(scoreLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(10));
|
|
|
|
|
panel.add(percentageLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(40));
|
|
|
|
|
panel.add(buttonPanel);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public JPanel buildChangePasswordView(PasswordChangeListener changeListener, Runnable backAction) {
|
|
|
|
|
JPanel panel = new JPanel();
|
|
|
|
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
|
|
|
panel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
|
|
|
|
|
|
|
|
|
|
JLabel titleLabel = new JLabel("修改密码");
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
|
|
|
|
|
titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JPanel inputPanel = new JPanel();
|
|
|
|
|
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
|
|
|
|
|
inputPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JPasswordField oldPasswordField = new JPasswordField(20);
|
|
|
|
|
JPasswordField newPasswordField = new JPasswordField(20);
|
|
|
|
|
JPasswordField confirmPasswordField = new JPasswordField(20);
|
|
|
|
|
|
|
|
|
|
JPanel oldPasswordPanel = createLabelFieldPanel("原密码:", oldPasswordField);
|
|
|
|
|
JPanel newPasswordPanel = createLabelFieldPanel("新密码:", newPasswordField);
|
|
|
|
|
JPanel confirmPasswordPanel = createLabelFieldPanel("确认密码:", confirmPasswordField);
|
|
|
|
|
|
|
|
|
|
inputPanel.add(oldPasswordPanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(newPasswordPanel);
|
|
|
|
|
inputPanel.add(Box.createVerticalStrut(15));
|
|
|
|
|
inputPanel.add(confirmPasswordPanel);
|
|
|
|
|
|
|
|
|
|
// 添加消息标签
|
|
|
|
|
JLabel messageLabel = new JLabel(" ");
|
|
|
|
|
messageLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
|
|
|
|
|
JPanel buttonPanel = new JPanel();
|
|
|
|
|
buttonPanel.setLayout(new FlowLayout());
|
|
|
|
|
buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
|
|
|
|
|
JButton submitButton = createStyledButton("确认修改", new Color(76, 175, 80), 120, 35);
|
|
|
|
|
JButton backButton = createStyledButton("返回", new Color(158, 158, 158), 120, 35);
|
|
|
|
|
|
|
|
|
|
submitButton.addActionListener(e -> {
|
|
|
|
|
String oldPassword = new String(oldPasswordField.getPassword());
|
|
|
|
|
String newPassword = new String(newPasswordField.getPassword());
|
|
|
|
|
String confirmPassword = new String(confirmPasswordField.getPassword());
|
|
|
|
|
|
|
|
|
|
// 客户端验证
|
|
|
|
|
if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmPassword.isEmpty()) {
|
|
|
|
|
messageLabel.setText("请填写所有密码字段!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!newPassword.equals(confirmPassword)) {
|
|
|
|
|
messageLabel.setText("两次输入的新密码不一致!");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用控制器处理密码修改
|
|
|
|
|
boolean success = changeListener.onPasswordChange(oldPassword, newPassword, confirmPassword);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
messageLabel.setText("密码修改成功!");
|
|
|
|
|
messageLabel.setForeground(Color.GREEN);
|
|
|
|
|
// 清空密码框
|
|
|
|
|
oldPasswordField.setText("");
|
|
|
|
|
newPasswordField.setText("");
|
|
|
|
|
confirmPasswordField.setText("");
|
|
|
|
|
} else {
|
|
|
|
|
messageLabel.setText("密码修改失败!请检查原密码是否正确,新密码是否符合要求。");
|
|
|
|
|
messageLabel.setForeground(Color.RED);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
backButton.addActionListener(e -> backAction.run());
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(submitButton);
|
|
|
|
|
buttonPanel.add(Box.createHorizontalStrut(20));
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
panel.add(Box.createVerticalStrut(10));
|
|
|
|
|
panel.add(titleLabel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(25));
|
|
|
|
|
panel.add(inputPanel);
|
|
|
|
|
panel.add(Box.createVerticalStrut(15));
|
|
|
|
|
panel.add(messageLabel); // 添加消息标签到面板
|
|
|
|
|
panel.add(Box.createVerticalStrut(10));
|
|
|
|
|
panel.add(buttonPanel);
|
|
|
|
|
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 辅助方法 ====================
|
|
|
|
|
|
|
|
|
|
private JPanel createLabelFieldPanel(String labelText, JComponent field) {
|
|
|
|
|
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
|
|
|
|
panel.add(new JLabel(labelText));
|
|
|
|
|
panel.add(field);
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JButton createStyledButton(String text, Color color, int width, int height) {
|
|
|
|
|
JButton button = new JButton(text);
|
|
|
|
|
button.setBackground(color);
|
|
|
|
|
button.setForeground(Color.WHITE);
|
|
|
|
|
button.setPreferredSize(new Dimension(width, height));
|
|
|
|
|
button.setOpaque(true);
|
|
|
|
|
button.setBorderPainted(false);
|
|
|
|
|
button.setFocusPainted(false);
|
|
|
|
|
return button;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private JButton createDifficultyButton(String text, Color color) {
|
|
|
|
|
JButton button = createStyledButton(text, color, 140, 45);
|
|
|
|
|
button.setFont(new Font("微软雅黑", Font.BOLD, 16));
|
|
|
|
|
button.setMaximumSize(new Dimension(140, 45));
|
|
|
|
|
button.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
|
|
|
return button;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 事件处理器 - 负责管理事件监听
|
|
|
|
|
*/
|
|
|
|
|
private class EventHandlers {
|
|
|
|
|
// 可以在这里添加复杂的事件处理逻辑
|
|
|
|
|
// 目前事件处理直接在内联监听器中实现
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =========================================================================
|
|
|
|
|
// 监听器接口定义
|
|
|
|
|
// =========================================================================
|
|
|
|
|
|
|
|
|
|
private interface LoginListener {
|
|
|
|
|
void onLogin(String email, String password);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface SendCodeListener {
|
|
|
|
|
boolean onSendCode(String username, String email);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface RegisterListener {
|
|
|
|
|
boolean onRegister(String username, String email, String code, String password, String confirmPassword);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface DifficultySelectListener {
|
|
|
|
|
void onDifficultySelected(String difficulty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface CountSubmitListener {
|
|
|
|
|
void onCountSubmit(int count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface AnswerSubmitListener {
|
|
|
|
|
void onAnswerSubmit(int answer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface PasswordChangeListener {
|
|
|
|
|
boolean onPasswordChange(String oldPassword, String newPassword, String confirmPassword);
|
|
|
|
|
}
|
|
|
|
|
}
|