Compare commits
3 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
c842e7f94f | 4 months ago |
|
|
05dbc0b18a | 4 months ago |
|
|
add58d0a32 | 4 months ago |
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="corretto-1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="corretto-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
@ -1,30 +0,0 @@
|
||||
package account;
|
||||
|
||||
public class Account {
|
||||
private String userName;
|
||||
private String password;
|
||||
private String userType;
|
||||
|
||||
public Account(String userName, String password,String userType) {
|
||||
this.userName = userName;
|
||||
this.password = password;
|
||||
this.userType = userType;
|
||||
}
|
||||
|
||||
public String getUserType() {
|
||||
return userType;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setUserType(String userType) {
|
||||
this.userType = userType;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
package account;
|
||||
|
||||
public interface AccountService {
|
||||
Account login(String username, String password);
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package account;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SimpleAccountService implements AccountService {
|
||||
private static final Map<String, Account> accounts = new HashMap<>();
|
||||
|
||||
static {
|
||||
accounts.put("张三1", new Account("张三1", "123", "小学"));
|
||||
accounts.put("张三2", new Account("张三2", "123", "小学"));
|
||||
accounts.put("张三3", new Account("张三3", "123", "小学"));
|
||||
accounts.put("李四1", new Account("李四1", "123", "初中"));
|
||||
accounts.put("李四2", new Account("李四2", "123", "初中"));
|
||||
accounts.put("李四3", new Account("李四3", "123", "初中"));
|
||||
accounts.put("王五1", new Account("王五1", "123", "高中"));
|
||||
accounts.put("王五2", new Account("王五2", "123", "高中"));
|
||||
accounts.put("王五3", new Account("王五3", "123", "高中"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account login(String username, String password) {
|
||||
Account account = accounts.get(username);
|
||||
if (account != null && account.getPassword().equals(password)) {
|
||||
return account;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,110 @@
|
||||
package com.student.mathquiz;
|
||||
|
||||
import com.student.mathquiz.view.*; // 导入所有 view controller
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class MainApp extends Application {
|
||||
|
||||
private Stage primaryStage;
|
||||
private BorderPane rootLayout;
|
||||
|
||||
// start 方法修改后
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
this.primaryStage = primaryStage;
|
||||
this.primaryStage.setTitle("小初高数学学习软件");
|
||||
initRootLayout();
|
||||
showLoginView();
|
||||
this.primaryStage.centerOnScreen();
|
||||
this.primaryStage.show();
|
||||
}
|
||||
|
||||
|
||||
public void initRootLayout() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
|
||||
rootLayout = loader.load();
|
||||
Scene scene = new Scene(rootLayout);
|
||||
primaryStage.setScene(scene);
|
||||
//primaryStage.show();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void showLoginView() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/LoginView.fxml"));
|
||||
AnchorPane view = loader.load();
|
||||
rootLayout.setCenter(view);
|
||||
LoginViewController controller = loader.getController();
|
||||
controller.setMainApp(this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void showRegisterView() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/RegisterView.fxml"));
|
||||
AnchorPane view = loader.load();
|
||||
rootLayout.setCenter(view);
|
||||
RegisterViewController controller = loader.getController();
|
||||
controller.setMainApp(this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void showMainMenuView() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/MainMenuView.fxml"));
|
||||
AnchorPane view = loader.load();
|
||||
rootLayout.setCenter(view);
|
||||
MainMenuViewController controller = loader.getController();
|
||||
controller.setMainApp(this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
|
||||
// ★ 看这里!我们现在真正地实现了这两个方法! ★
|
||||
// ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
|
||||
public void showQuizView() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/QuizView.fxml"));
|
||||
AnchorPane view = loader.load();
|
||||
rootLayout.setCenter(view);
|
||||
QuizViewController controller = loader.getController();
|
||||
controller.setMainApp(this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void showScoreView() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/ScoreView.fxml"));
|
||||
AnchorPane view = loader.load();
|
||||
rootLayout.setCenter(view);
|
||||
ScoreViewController controller = loader.getController();
|
||||
controller.setMainApp(this);
|
||||
// 我们可以先给一个假分数,让你看到效果
|
||||
controller.setScore(80);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- LoginView.fxml -->
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.student.mathquiz.view.LoginViewController">
|
||||
<VBox alignment="CENTER" layoutX="150.0" layoutY="50.0" prefHeight="300.0" prefWidth="300.0" spacing="20.0">
|
||||
<Label text="用户登录"><font><Font size="24.0" /></font></Label>
|
||||
<TextField fx:id="emailField" promptText="邮箱" />
|
||||
<PasswordField fx:id="passwordField" promptText="密码" />
|
||||
<Button onAction="#handleLogin" text="登录" />
|
||||
<Button onAction="#handleGoToRegister" text="还没有账户?去注册" style="-fx-background-color: transparent; -fx-border-color: transparent; -fx-underline: true; -fx-cursor: hand;" />
|
||||
<Label fx:id="statusLabel" textFill="RED" />
|
||||
</VBox>
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,37 @@
|
||||
// LoginViewController.java
|
||||
package com.student.mathquiz.view;
|
||||
|
||||
import com.student.mathquiz.MainApp;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
public class LoginViewController {
|
||||
@FXML private TextField emailField;
|
||||
@FXML private PasswordField passwordField;
|
||||
@FXML private Label statusLabel;
|
||||
|
||||
private MainApp mainApp;
|
||||
|
||||
public void setMainApp(MainApp mainApp) {
|
||||
this.mainApp = mainApp;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleLogin() {
|
||||
// TODO: 在这里调用后端 loginService.login(...)
|
||||
if ("test".equals(emailField.getText()) && "123".equals(passwordField.getText())) {
|
||||
// 登录成功,让 MainApp 切换到主菜单界面
|
||||
mainApp.showMainMenuView();
|
||||
} else {
|
||||
statusLabel.setText("邮箱或密码错误!");
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleGoToRegister() {
|
||||
// 让 MainApp 切换到注册界面
|
||||
mainApp.showRegisterView();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- MainMenuView.fxml -->
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.student.mathquiz.view.MainMenuViewController">
|
||||
<VBox alignment="CENTER" layoutX="200.0" layoutY="100.0" prefHeight="200.0" prefWidth="200.0" spacing="20.0">
|
||||
<Label text="请选择难度"><font><Font size="24.0" /></font></Label>
|
||||
<Button onAction="#handlePrimary" prefWidth="100.0" text="小学" />
|
||||
<Button onAction="#handleMiddle" prefWidth="100.0" text="初中" />
|
||||
<Button onAction="#handleHigh" prefWidth="100.0" text="高中" />
|
||||
</VBox>
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,32 @@
|
||||
// MainMenuViewController.java
|
||||
package com.student.mathquiz.view;
|
||||
|
||||
import com.student.mathquiz.MainApp;
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
public class MainMenuViewController {
|
||||
private MainApp mainApp;
|
||||
|
||||
public void setMainApp(MainApp mainApp) {
|
||||
this.mainApp = mainApp;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handlePrimary() {
|
||||
System.out.println("选择了小学难度");
|
||||
// TODO: 调用 mainApp.showQuizView("小学");
|
||||
mainApp.showQuizView();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleMiddle() {
|
||||
System.out.println("选择了初中难度");
|
||||
mainApp.showQuizView();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleHigh() {
|
||||
System.out.println("选择了高中难度");
|
||||
mainApp.showQuizView();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- RegisterView.fxml -->
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.student.mathquiz.view.RegisterViewController">
|
||||
<VBox alignment="CENTER" layoutX="150.0" layoutY="25.0" prefHeight="350.0" prefWidth="300.0" spacing="15.0">
|
||||
<Label text="用户注册"><font><Font size="24.0" /></font></Label>
|
||||
<TextField fx:id="emailField" promptText="邮箱" />
|
||||
<Button onAction="#handleSendCode" text="发送验证码" />
|
||||
<TextField fx:id="codeField" promptText="验证码" />
|
||||
<PasswordField fx:id="passwordField1" promptText="设置密码 (6-10位,含大小写字母和数字)" />
|
||||
<PasswordField fx:id="passwordField2" promptText="确认密码" />
|
||||
<Button onAction="#handleRegister" text="注册" />
|
||||
<Button onAction="#handleGoToLogin" text="已有账户?去登录" style="-fx-background-color: transparent; -fx-border-color: transparent; -fx-underline: true; -fx-cursor: hand;" />
|
||||
<Label fx:id="statusLabel" textFill="RED" wrapText="true" />
|
||||
</VBox>
|
||||
</AnchorPane>
|
||||
@ -0,0 +1,59 @@
|
||||
// RegisterViewController.java
|
||||
package com.student.mathquiz.view;
|
||||
|
||||
import com.student.mathquiz.MainApp;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
public class RegisterViewController {
|
||||
public TextField codeField;
|
||||
public TextField emailField;
|
||||
@FXML private Label statusLabel;
|
||||
|
||||
private MainApp mainApp;
|
||||
|
||||
public void setMainApp(MainApp mainApp) {
|
||||
this.mainApp = mainApp;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleSendCode() {
|
||||
// TODO: 在这里调用后端 userService.sendVerificationCode(...)
|
||||
String email = emailField.getText();
|
||||
|
||||
// TODO: 在这里先加一个邮箱格式校验
|
||||
|
||||
String code = EmailService.generateVerificationCode();
|
||||
|
||||
// ★★★ 在后台线程中发送邮件,防止界面卡死! ★★★
|
||||
new Thread(() -> {
|
||||
boolean success = EmailService.sendVerificationEmail(email, code);
|
||||
|
||||
// 在 JavaFX 主线程中更新界面
|
||||
Platform.runLater(() -> {
|
||||
if (success) {
|
||||
statusLabel.setText("验证码已发送至您的邮箱,请查收!");
|
||||
// TODO: 把 code 和 email 存起来,用于稍后的验证
|
||||
} else {
|
||||
statusLabel.setText("验证码发送失败,请检查邮箱地址或网络!");
|
||||
}
|
||||
});
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleRegister() {
|
||||
// TODO: 在这里进行输入校验,并调用后端 userService.register(...)
|
||||
statusLabel.setText("注册成功(伪)!请登录。");
|
||||
mainApp.showLoginView();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleGoToLogin() {
|
||||
mainApp.showLoginView();
|
||||
}
|
||||
}
|
||||
// 在 RegisterViewController.java 里
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
|
||||
<BorderPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" />
|
||||
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.student.mathquiz.view.ScoreViewController">
|
||||
<children>
|
||||
<VBox alignment="CENTER" layoutX="200.0" layoutY="100.0" prefHeight="200.0" prefWidth="200.0" spacing="20.0">
|
||||
<children>
|
||||
<Label text="测试完成!">
|
||||
<font>
|
||||
<Font name="System Bold" size="24.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label fx:id="scoreLabel" text="你的分数是: 100">
|
||||
<font>
|
||||
<Font size="18.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Button onAction="#handleTryAgain" text="再做一组" />
|
||||
<Button onAction="#handleExit" text="退出程序" />
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
@ -1,29 +0,0 @@
|
||||
package persistence;
|
||||
|
||||
import question.Question;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
public class FileSaver {
|
||||
public static void saveQuestions(String username, List<Question> questions) {
|
||||
File dir = new File(username);
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
String filename = LocalDateTime.now().format(
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + ".txt";
|
||||
|
||||
try (FileWriter writer = new FileWriter(new File(dir, filename))) {
|
||||
for (int i = 0; i < questions.size(); i++) {
|
||||
writer.write((i + 1) + ". " + questions.get(i).getQuestion() + "\n\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("题目已生成并保存!");
|
||||
}
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
package question;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class HighQuestionGenerator implements QuestionGenerator {
|
||||
private static final Random random = new Random();
|
||||
private final QuestionGenerator primaryGenerator = new PrimaryQuestionGenerator();
|
||||
|
||||
@Override
|
||||
public Question generateQuestion() {
|
||||
Question q = primaryGenerator.generateQuestion();
|
||||
String[] funcs = {"sin", "cos", "tan"};
|
||||
String func = funcs[random.nextInt(funcs.length)];
|
||||
return new Question(func + "(" + q.getQuestion() + ")", evaluate(func, q.getQuestion()));
|
||||
}
|
||||
|
||||
private String evaluate(String func, String expr) {
|
||||
try {
|
||||
javax.script.ScriptEngineManager mgr = new javax.script.ScriptEngineManager();
|
||||
javax.script.ScriptEngine engine = mgr.getEngineByName("JavaScript");
|
||||
return String.valueOf(engine.eval("Math." + func + "(Math.toRadians(" + expr + "))"));
|
||||
} catch (Exception e) {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package question;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class MiddleQuestionGenerator implements QuestionGenerator {
|
||||
private static final Random random = new Random();
|
||||
private final QuestionGenerator primaryGenerator = new PrimaryQuestionGenerator();
|
||||
|
||||
@Override
|
||||
public Question generateQuestion() {
|
||||
Question q = primaryGenerator.generateQuestion();
|
||||
if (random.nextBoolean()) {
|
||||
return new Question(q.getQuestion() + " ^ 2", evaluate(q.getQuestion() + "^2"));
|
||||
} else {
|
||||
return new Question("√" + q.getQuestion(), evaluate("Math.sqrt(" + q.getQuestion() + ")"));
|
||||
}
|
||||
}
|
||||
|
||||
private String evaluate(String expr) {
|
||||
try {
|
||||
javax.script.ScriptEngineManager mgr = new javax.script.ScriptEngineManager();
|
||||
javax.script.ScriptEngine engine = mgr.getEngineByName("JavaScript");
|
||||
return String.valueOf(engine.eval(expr.replace("^", "**")));
|
||||
} catch (Exception e) {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
package question;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class PrimaryQuestionGenerator implements QuestionGenerator {
|
||||
private static final Random random = new Random();
|
||||
|
||||
@Override
|
||||
public Question generateQuestion() {
|
||||
int numOperands = random.nextInt(5) + 1;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int currentValue = random.nextInt(100) + 1;
|
||||
sb.append(currentValue);
|
||||
|
||||
for (int i = 1; i < numOperands; i++) {
|
||||
String[] ops = {"+", "-", "*", "/"};
|
||||
String op;
|
||||
int nextVal;
|
||||
do {
|
||||
op = ops[random.nextInt(ops.length)];
|
||||
nextVal = random.nextInt(100) + 1;
|
||||
} while ((op.equals("-") && currentValue < nextVal) ||
|
||||
(op.equals("/") && (nextVal == 0 || currentValue % nextVal != 0)));
|
||||
|
||||
sb.append(" ").append(op).append(" ").append(nextVal);
|
||||
switch (op) {
|
||||
case "+": currentValue += nextVal; break;
|
||||
case "-": currentValue -= nextVal; break;
|
||||
case "*": currentValue *= nextVal; break;
|
||||
case "/": currentValue /= nextVal; break;
|
||||
}
|
||||
}
|
||||
|
||||
String expr = addParentheses(sb.toString());
|
||||
return new Question(expr, evaluate(expr));
|
||||
}
|
||||
|
||||
private String addParentheses(String expr) {
|
||||
String[] tokens = expr.split(" ");
|
||||
if (tokens.length < 3) return expr;
|
||||
|
||||
int start = random.nextInt(tokens.length / 2) * 2;
|
||||
int end = start + 2 + random.nextInt((tokens.length - start) / 2) * 2;
|
||||
end = Math.min(end, tokens.length - 1);
|
||||
|
||||
StringBuilder newExpr = new StringBuilder();
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
if (i == start) newExpr.append("(");
|
||||
newExpr.append(tokens[i]);
|
||||
if (i == end) newExpr.append(")");
|
||||
if (i != tokens.length - 1) newExpr.append(" ");
|
||||
}
|
||||
return newExpr.toString();
|
||||
}
|
||||
|
||||
private String evaluate(String expr) {
|
||||
try {
|
||||
javax.script.ScriptEngineManager mgr = new javax.script.ScriptEngineManager();
|
||||
javax.script.ScriptEngine engine = mgr.getEngineByName("JavaScript");
|
||||
return String.valueOf(engine.eval(expr));
|
||||
} catch (Exception e) {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
package question;
|
||||
|
||||
public class Question {
|
||||
private String question;
|
||||
private String answer;
|
||||
|
||||
public Question(String question, String answer) {
|
||||
this.question = question;
|
||||
this.answer = answer;
|
||||
}
|
||||
|
||||
public String getQuestion() {
|
||||
return question;
|
||||
}
|
||||
|
||||
public String getAnswer() {
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
package question;
|
||||
|
||||
public interface QuestionGenerator {
|
||||
Question generateQuestion();
|
||||
}
|
||||
Loading…
Reference in new issue