parent
8f97b4fc83
commit
76a3573156
@ -0,0 +1,29 @@
|
||||
### IntelliJ IDEA ###
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
@ -0,0 +1,10 @@
|
||||
<component name="libraryTable">
|
||||
<library name="lib">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/lib" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib" recursive="false" />
|
||||
</library>
|
||||
</component>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21_PREVIEW" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/Group-HD.iml" filepath="$PROJECT_DIR$/Group-HD.iml" />
|
||||
</modules>
|
||||
</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>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="lib" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,19 @@
|
||||
1. 78 / 96 - 22
|
||||
|
||||
2. 15 - 17 * (49 / 15)
|
||||
|
||||
3. 66 + 28 / 8 + (1 / 25)
|
||||
|
||||
4. 16 * 2
|
||||
|
||||
5. 26 * (98 * 90)
|
||||
|
||||
6. 4 + 89 * (70 / 3)
|
||||
|
||||
7. 41 + 36 + 55 + 9
|
||||
|
||||
8. 79 * 72 - 19 * 32
|
||||
|
||||
9. 2 - 2
|
||||
|
||||
10. (32 - 82) + 16
|
||||
@ -0,0 +1,19 @@
|
||||
1. 70^2 / 64
|
||||
|
||||
2. 11^2 + 31 + 85^2 - 61
|
||||
|
||||
3. √95 - 73^2 + 54^2
|
||||
|
||||
4. 53 - (√44 / 53 / 5^2) * 10^2
|
||||
|
||||
5. 5^2 * 75^2 / √24 - √20 + 74^2
|
||||
|
||||
6. √74 / 82
|
||||
|
||||
7. 31 * 5 * √42 / 53^2 + √19
|
||||
|
||||
8. 48 + 24^2 / 12^2 - 87
|
||||
|
||||
9. (37 * 38^2 + √82 / 27) + 32
|
||||
|
||||
10. 95 - √72
|
||||
@ -0,0 +1,19 @@
|
||||
1. 47 * sin(70) * 75 - cos(16)
|
||||
|
||||
2. sin(65) * 38 - 16 / 68
|
||||
|
||||
3. 78 * sin(50) / cos(70) * tan(52)
|
||||
|
||||
4. (cos(70) + sin(12) + 85) - cos(46)
|
||||
|
||||
5. cos(60) / tan(4)
|
||||
|
||||
6. 70 * sin(28) * sin(7)
|
||||
|
||||
7. tan(74) - cos(55) - cos(42) + tan(38)
|
||||
|
||||
8. tan(62) + 45
|
||||
|
||||
9. 52 + sin(33)
|
||||
|
||||
10. sin(40) * 29
|
||||
@ -0,0 +1,19 @@
|
||||
1. 5 - 41
|
||||
|
||||
2. 12 / (22 / 21 + 5) + 60
|
||||
|
||||
3. 88 * (22 * 75)
|
||||
|
||||
4. 5 - 23
|
||||
|
||||
5. 72 * 61 / 59 + 40
|
||||
|
||||
6. 2 * 50
|
||||
|
||||
7. (37 * 99) - 92 * 43
|
||||
|
||||
8. 85 * 88
|
||||
|
||||
9. 38 / 98 - 75 - 71 / 74
|
||||
|
||||
10. 63 / (44 - 25)
|
||||
@ -0,0 +1,59 @@
|
||||
1. 6 + 63 - 75 - 63 / 89
|
||||
|
||||
2. 38 - (63 * 76) + 41
|
||||
|
||||
3. 31 * 90 - 8 + 28 + 19
|
||||
|
||||
4. 21 - 94
|
||||
|
||||
5. 66 + (49 / 9)
|
||||
|
||||
6. 36 * 30 * 74
|
||||
|
||||
7. 63 / 1 / 57 - (12 - 60)
|
||||
|
||||
8. (91 - 68 + 66) * 7 * 83
|
||||
|
||||
9. 68 - 47 / 15 / 84
|
||||
|
||||
10. 38 - 47 * 19
|
||||
|
||||
11. 4 * 19
|
||||
|
||||
12. 48 / 38 - 62
|
||||
|
||||
13. 27 - 13
|
||||
|
||||
14. 32 * 61 / 25 + 11
|
||||
|
||||
15. 10 - 71
|
||||
|
||||
16. 92 - (27 + 99 - 57)
|
||||
|
||||
17. 9 / (79 - 59)
|
||||
|
||||
18. 76 - (68 + 73 + 20)
|
||||
|
||||
19. 97 - 1
|
||||
|
||||
20. 66 - 43 * 19 / 2 / 2
|
||||
|
||||
21. 78 / 35 / 94 + 12 - 16
|
||||
|
||||
22. 54 + 96
|
||||
|
||||
23. 34 - 5
|
||||
|
||||
24. 4 - 39
|
||||
|
||||
25. 58 / 17 / 45 * 51
|
||||
|
||||
26. 3 + (71 - 43)
|
||||
|
||||
27. 21 - (93 - 83)
|
||||
|
||||
28. 46 / 10 / 20 + 42
|
||||
|
||||
29. 35 + (37 - 90)
|
||||
|
||||
30. 83 * 82 - 11
|
||||
@ -0,0 +1,59 @@
|
||||
1. (58 + 75) / 19
|
||||
|
||||
2. 99 * 13 / 10
|
||||
|
||||
3. 97 + 77
|
||||
|
||||
4. (93 + 10) - 26
|
||||
|
||||
5. 21 + 77 - 78 / (56 - 28)
|
||||
|
||||
6. 97 + 19
|
||||
|
||||
7. 97 * (31 + 25 * 33 * 68)
|
||||
|
||||
8. 90 / 18 - 80 - 51
|
||||
|
||||
9. 53 / 28 - 39 + 21
|
||||
|
||||
10. 58 - 94
|
||||
|
||||
11. 10 - 85
|
||||
|
||||
12. 100 - 42 * 9 - 66 - 49
|
||||
|
||||
13. 22 / (19 + 65 / 17)
|
||||
|
||||
14. 48 + (5 + 2) - 25
|
||||
|
||||
15. 91 * 9 * (26 + 70) / 93
|
||||
|
||||
16. 20 + 3 / 42
|
||||
|
||||
17. 24 / 39 * 69
|
||||
|
||||
18. (88 + 55) + 14 * 42
|
||||
|
||||
19. 90 / 16 / 9 * 75
|
||||
|
||||
20. 84 * 65 / (84 - 70)
|
||||
|
||||
21. 30 * (85 / 83)
|
||||
|
||||
22. 89 / 15 - 55 - 60 + 37
|
||||
|
||||
23. (12 * 66) / 82
|
||||
|
||||
24. (27 + 47) / 85
|
||||
|
||||
25. 12 * 80 + 27 * 86 * 80
|
||||
|
||||
26. 47 + 88 + (45 * 29)
|
||||
|
||||
27. 93 + 7 + 28 + 85 / 92
|
||||
|
||||
28. 9 * 4 + (62 / 31)
|
||||
|
||||
29. 6 - 26
|
||||
|
||||
30. (58 * 70) + 55
|
||||
@ -0,0 +1,19 @@
|
||||
1. 14 * 25 * (59 * 79)
|
||||
|
||||
2. 21 / 91 / 4 - (87 * 16)
|
||||
|
||||
3. 46 / 20 + 87 * 59
|
||||
|
||||
4. 86 / (7 * 59)
|
||||
|
||||
5. 85 / 35 * 30
|
||||
|
||||
6. 9 - 88
|
||||
|
||||
7. 27 + 10
|
||||
|
||||
8. 94 - 76 / 59
|
||||
|
||||
9. 37 / (5 / 89)
|
||||
|
||||
10. 25 * 46 + 28
|
||||
@ -0,0 +1,19 @@
|
||||
1. (39 + 54^2 * 23) / 1 * 50
|
||||
|
||||
2. 69^2 - 82
|
||||
|
||||
3. √36 + 49
|
||||
|
||||
4. √44 + 45 * 95
|
||||
|
||||
5. 10 - 76^2 - 70^2
|
||||
|
||||
6. √72 * √98 * 16
|
||||
|
||||
7. (27^2 / 48) / 10
|
||||
|
||||
8. 9 + √40 - 25 / √69 / 13^2
|
||||
|
||||
9. 73 * (8^2 / 61 - 96)
|
||||
|
||||
10. √34 / (√64 * 79)
|
||||
@ -0,0 +1,19 @@
|
||||
1. 57 / cos(76)
|
||||
|
||||
2. sin(5) - sin(22)
|
||||
|
||||
3. sin(90) + sin(66) * 79
|
||||
|
||||
4. (sin(42) + tan(30)) - cos(68)
|
||||
|
||||
5. tan(96) - tan(54) / tan(30)
|
||||
|
||||
6. tan(24) / 73
|
||||
|
||||
7. 76 + sin(86) - sin(98) * 25
|
||||
|
||||
8. 16 / cos(84) * 22
|
||||
|
||||
9. cos(77) + sin(21) * 14
|
||||
|
||||
10. sin(19) * cos(53) / 28
|
||||
@ -0,0 +1,19 @@
|
||||
1. 40 * 27 + 23 - 30
|
||||
|
||||
2. 27 / 53
|
||||
|
||||
3. 55 + 18 / 51 + 70 * 20
|
||||
|
||||
4. 66 - 81
|
||||
|
||||
5. 68 + (87 / 23)
|
||||
|
||||
6. 48 / 62
|
||||
|
||||
7. (79 + 74 * 6) + 99
|
||||
|
||||
8. 66 * 67
|
||||
|
||||
9. 20 + 5 - 43 * 28 * 16
|
||||
|
||||
10. (46 + 78) + 1
|
||||
@ -0,0 +1,19 @@
|
||||
1. 81 / 75 - 19
|
||||
|
||||
2. 95 + 44
|
||||
|
||||
3. 6 + 8 / 22 + (57 / 34)
|
||||
|
||||
4. 22 + 85 / 59
|
||||
|
||||
5. 60 + (30 * 8)
|
||||
|
||||
6. 63 - (38 / 14 * 93)
|
||||
|
||||
7. 64 / 88 * 54
|
||||
|
||||
8. 79 * (34 + 5) - 47
|
||||
|
||||
9. 73 - 84 * 29 + 26 - 44
|
||||
|
||||
10. 9 * 75 - 38 / 25 * 95
|
||||
@ -0,0 +1,19 @@
|
||||
1. 26 + 25 * 13
|
||||
|
||||
2. 22 * 29 + 21 / 42 + 10
|
||||
|
||||
3. 30 - (44 - 6)
|
||||
|
||||
4. 20 / (58 + 76)
|
||||
|
||||
5. 2 / 57
|
||||
|
||||
6. 27 - 58
|
||||
|
||||
7. 43 / 7
|
||||
|
||||
8. 21 / 81 - 34 + 26
|
||||
|
||||
9. 21 / 42
|
||||
|
||||
10. 32 - 4 - 8 / 73
|
||||
@ -0,0 +1,19 @@
|
||||
1. 25^2 / 69 - 35
|
||||
|
||||
2. 72^2 * 24^2 + 57^2 - 36^2
|
||||
|
||||
3. √16 / 14^2
|
||||
|
||||
4. (29^2 + √30 - 77) / 25 * √91
|
||||
|
||||
5. 52 + 31^2
|
||||
|
||||
6. (46 / √16) - 49
|
||||
|
||||
7. √89 / √21
|
||||
|
||||
8. 88 + 8 + √92 / 34^2
|
||||
|
||||
9. 55 - (11 / 53^2)
|
||||
|
||||
10. 55^2 - (√51 + √30)
|
||||
@ -0,0 +1,19 @@
|
||||
1. sin(87) + cos(71)
|
||||
|
||||
2. (83 * tan(71) / cos(20)) - 61
|
||||
|
||||
3. (70 / cos(95)) / 1 * sin(19) * 24
|
||||
|
||||
4. 68 + 50 / 96 + cos(15) * sin(76)
|
||||
|
||||
5. 21 * (21 - cos(98))
|
||||
|
||||
6. sin(37) + tan(2) * sin(48) * 77
|
||||
|
||||
7. 7 / cos(17) * (tan(10) * tan(87))
|
||||
|
||||
8. (cos(46) / 4 / 34 * sin(88)) - sin(82)
|
||||
|
||||
9. tan(49) * 22 + tan(80)
|
||||
|
||||
10. 25 * sin(60)
|
||||
@ -0,0 +1,39 @@
|
||||
1. 29 * sin(47) + sin(92) * 57 - sin(61)
|
||||
|
||||
2. tan(58) - (tan(89) + tan(59) + cos(15))
|
||||
|
||||
3. tan(83) - sin(95) / sin(85)
|
||||
|
||||
4. sin(42) + 1 / sin(14) + tan(66) + 94
|
||||
|
||||
5. 97 * 76 - cos(65) - 86
|
||||
|
||||
6. 67 / 11 / 31 + 98 / cos(51)
|
||||
|
||||
7. tan(6) * tan(77)
|
||||
|
||||
8. sin(11) - (52 / 13 + sin(8))
|
||||
|
||||
9. cos(16) * cos(62)
|
||||
|
||||
10. 94 * sin(12) + 10 - 32 - 56
|
||||
|
||||
11. 20 + cos(14)
|
||||
|
||||
12. (cos(66) * 74) * 55 / 69
|
||||
|
||||
13. sin(87) - 32 * tan(54) / tan(9) / sin(96)
|
||||
|
||||
14. sin(37) / tan(47)
|
||||
|
||||
15. tan(85) + sin(81) - sin(67)
|
||||
|
||||
16. 90 + tan(80)
|
||||
|
||||
17. cos(6) + sin(37)
|
||||
|
||||
18. (tan(42) + 99 + 25) * 49
|
||||
|
||||
19. 45 + sin(86)
|
||||
|
||||
20. cos(10) / cos(2) / 23 / 73 * sin(22)
|
||||
@ -0,0 +1,57 @@
|
||||
1. 50 + 93^2
|
||||
|
||||
2. 40^2 - 61 - (2 * 7) * 40
|
||||
|
||||
3. √43 / √62 / 55 / √59 - 54
|
||||
|
||||
4. 11^2 * 20
|
||||
|
||||
5. 25^2 - 98 / 46 - 11
|
||||
|
||||
6. √64 * 46^2 / 12^2 - 67^2
|
||||
|
||||
7. √69 + √78 * 94 * √22
|
||||
|
||||
8. √63 / 70 + (47 * 11^2)
|
||||
|
||||
9. √70 / 98^2
|
||||
|
||||
10. 54^2 - √62
|
||||
|
||||
11. 51 * √72
|
||||
|
||||
12. √91 / 60^2 + √11 + (1^2 + 64)
|
||||
|
||||
13. √57 + √22 * 74
|
||||
|
||||
14. 37^2 * 23^2 / 94 - (27^2 - √35)
|
||||
|
||||
15. 31 * 69^2 / (√53 * 98)
|
||||
|
||||
16. √58 / 32^2 - (√44 / 91^2)
|
||||
|
||||
17. 16^2 * 9 * 70^2
|
||||
|
||||
18. 90 + √8 - √17 * 35 + 10
|
||||
|
||||
19. 97^2 + (√37 - 35 - 25^2)
|
||||
|
||||
20. 54^2 + 22^2 + √81 / √43 + 50
|
||||
|
||||
21. 96^2 - 11
|
||||
|
||||
22. √30 * 56^2 - 25^2 - 88
|
||||
|
||||
23. √97 * 35^2
|
||||
|
||||
24. √24 - √65 + (80 * 14^2 - 12^2)
|
||||
|
||||
25. 49^2 * 94 - 10 * 41^2
|
||||
|
||||
26. 59^2 / 45 / 32
|
||||
|
||||
27. 42 * 53^2 / 41 + 66 + 67
|
||||
|
||||
28. 89^2 * √92 - √3
|
||||
|
||||
29. 56 * 96^2
|
||||
@ -0,0 +1,19 @@
|
||||
1. 7 + 28 - 87 / 93 - 45
|
||||
|
||||
2. 74 / 15 - 19 + (98 + 16)
|
||||
|
||||
3. 17 - (68 * 38) * 37
|
||||
|
||||
4. 2 - 54 / (38 - 56)
|
||||
|
||||
5. 61 * 89 * 62
|
||||
|
||||
6. 14 - 58 * (65 + 66)
|
||||
|
||||
7. (39 + 25) * 23 * 78 + 67
|
||||
|
||||
8. 18 * (14 / 27 - 85)
|
||||
|
||||
9. 87 - 99 - 59
|
||||
|
||||
10. 48 - 22 / 42
|
||||
@ -0,0 +1,7 @@
|
||||
package model;
|
||||
|
||||
public enum Grade {
|
||||
primary,
|
||||
middle,
|
||||
high
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package model;
|
||||
|
||||
public class HighMaker extends Student {
|
||||
final static String[] binaryOps = {"+", "-", "*", "/"}; // 操作符
|
||||
final static String[] trigOps = {"sin", "cos", "tan"};
|
||||
int operandCount;
|
||||
String[] questionParts; // 操作数
|
||||
boolean[] specialOpFlags; // 特殊操作符索引序列
|
||||
int parenStart;
|
||||
int parenEnd;
|
||||
|
||||
public HighMaker(String name, String password, String path) {
|
||||
super(name, password, path);
|
||||
}
|
||||
|
||||
// 数据预处理
|
||||
public void getRandom() {
|
||||
this.operandCount = random.nextInt(4) + 2;
|
||||
this.questionParts = new String[this.operandCount];
|
||||
|
||||
// 使用基类方法随机决定特殊操作符的数量和位置
|
||||
this.specialOpFlags = randomMaker(this.operandCount);
|
||||
|
||||
// 生成题目各部分
|
||||
for (int i = 0; i < operandCount; i++) {
|
||||
int operand = random.nextInt(100) + 1;
|
||||
if (specialOpFlags[i]) {
|
||||
String op = trigOps[random.nextInt(trigOps.length)];
|
||||
questionParts[i] = op + "(" + operand + ")";
|
||||
} else {
|
||||
questionParts[i] = String.valueOf(operand);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用基类方法生成有效括号
|
||||
int[] parenPos = bracketMaker(this.operandCount);
|
||||
this.parenStart = parenPos[0];
|
||||
this.parenEnd = parenPos[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeOneQuestion() {
|
||||
getRandom();
|
||||
StringBuilder question = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < operandCount; i++) {
|
||||
if (i == parenStart) {
|
||||
question.append("(");
|
||||
}
|
||||
question.append(questionParts[i]);
|
||||
if (i == parenEnd) {
|
||||
question.append(")");
|
||||
}
|
||||
|
||||
if (i < operandCount - 1) {
|
||||
String op = binaryOps[random.nextInt(binaryOps.length)];
|
||||
question.append(" ").append(op).append(" ");
|
||||
}
|
||||
}
|
||||
return question.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package model;
|
||||
|
||||
public class MiddleMaker extends Student {
|
||||
final static String[] binaryOps = {"+", "-", "*", "/"}; // 操作符
|
||||
final static String[] unaryOps = {"^2", "√"};
|
||||
int operandCount;
|
||||
String[] questionParts; // 操作数
|
||||
boolean[] specialOpFlags; // 特殊操作符索引序列
|
||||
int parenStart;
|
||||
int parenEnd;
|
||||
|
||||
public MiddleMaker(String name, String password, String path) {
|
||||
super(name, password, path);
|
||||
}
|
||||
|
||||
// 数据预处理
|
||||
public void getRandom() {
|
||||
this.operandCount = random.nextInt(4) + 2;
|
||||
this.questionParts = new String[this.operandCount];
|
||||
|
||||
// 使用基类方法随机决定特殊操作符的数量和位置
|
||||
this.specialOpFlags = randomMaker(this.operandCount);
|
||||
|
||||
// 生成题目各部分
|
||||
for (int i = 0; i < this.operandCount; i++) {
|
||||
int operand = random.nextInt(100) + 1;
|
||||
if (this.specialOpFlags[i]) {
|
||||
String op = unaryOps[random.nextInt(unaryOps.length)];
|
||||
if (op.equals("√")) {
|
||||
this.questionParts[i] = op + operand;
|
||||
} else {
|
||||
this.questionParts[i] = operand + op;
|
||||
}
|
||||
} else {
|
||||
this.questionParts[i] = String.valueOf(operand);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用基类方法生成有效括号
|
||||
int[] parenPos = bracketMaker(this.operandCount);
|
||||
this.parenStart = parenPos[0];
|
||||
this.parenEnd = parenPos[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeOneQuestion() {
|
||||
getRandom();
|
||||
StringBuilder question = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < operandCount; i++) {
|
||||
if (i == parenStart) {
|
||||
question.append("(");
|
||||
}
|
||||
question.append(questionParts[i]);
|
||||
if (i == parenEnd) {
|
||||
question.append(")");
|
||||
}
|
||||
if (i < operandCount - 1) {
|
||||
question.append(" ").append(binaryOps[random.nextInt(binaryOps.length)]).append(" ");
|
||||
}
|
||||
}
|
||||
return question.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package model;
|
||||
|
||||
public class PrimaryMaker extends Student {
|
||||
final static char[] operators = {'+', '-', '*', '/'}; // 操作符
|
||||
int operandCount; // 操作数个数
|
||||
int[] operands; // 操作数列表
|
||||
int parenStart; // 左括号索引
|
||||
int parenEnd; // 右括号
|
||||
|
||||
public PrimaryMaker(String name, String password, String path) {
|
||||
super(name, password, path);
|
||||
}
|
||||
|
||||
// 数据预处理
|
||||
public void getRandom() {
|
||||
// 随机决定操作数个数
|
||||
this.operandCount = random.nextInt(4) + 2;
|
||||
this.operands = new int[operandCount];
|
||||
for (int j = 0; j < operandCount; j++) {
|
||||
operands[j] = random.nextInt(100) + 1;
|
||||
}
|
||||
|
||||
// 使用基类方法生成有效括号
|
||||
int[] parenPos = bracketMaker(this.operandCount);
|
||||
this.parenStart = parenPos[0];
|
||||
this.parenEnd = parenPos[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeOneQuestion() {
|
||||
getRandom();
|
||||
StringBuilder question = new StringBuilder();
|
||||
|
||||
for (int j = 0; j < this.operandCount; j++) {
|
||||
if (j == this.parenStart) {
|
||||
question.append("(");
|
||||
}
|
||||
question.append(operands[j]);
|
||||
if (j == this.parenEnd) {
|
||||
question.append(")");
|
||||
}
|
||||
|
||||
if (j < this.operandCount - 1) {
|
||||
char op = operators[random.nextInt(operators.length)];
|
||||
if (op == '/') {
|
||||
this.operands[j + 1] = this.operands[j + 1] == 0 ? 1 : this.operands[j + 1];
|
||||
}
|
||||
question.append(" ").append(op).append(" ");
|
||||
}
|
||||
}
|
||||
return question.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package model;
|
||||
|
||||
/**
|
||||
* 题目类
|
||||
* 包含题干、选项和正确答案
|
||||
*/
|
||||
public class Question {
|
||||
private final String questionText;
|
||||
private final String[] options;
|
||||
private final int correctAnswer;
|
||||
private final String expression;
|
||||
|
||||
/**
|
||||
* 构造题目对象
|
||||
*
|
||||
* @param expression 数学表达式
|
||||
* @param questionText 题目文本
|
||||
* @param options 选项数组(4个选项)
|
||||
* @param correctAnswer 正确答案索引(0-3)
|
||||
*/
|
||||
public Question(String expression, String questionText, String[] options,
|
||||
int correctAnswer) {
|
||||
this.expression = expression;
|
||||
this.questionText = questionText;
|
||||
this.options = options;
|
||||
this.correctAnswer = correctAnswer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取题目文本
|
||||
*
|
||||
* @return 题目文本
|
||||
*/
|
||||
public String getQuestionText() {
|
||||
return questionText;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选项数组
|
||||
*
|
||||
* @return 选项数组
|
||||
*/
|
||||
public String[] getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取正确答案索引
|
||||
*
|
||||
* @return 正确答案索引
|
||||
*/
|
||||
public int getCorrectAnswer() {
|
||||
return correctAnswer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数学表达式
|
||||
*
|
||||
* @return 数学表达式
|
||||
*/
|
||||
public String getExpression() {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package model;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public abstract class Student {
|
||||
protected String name;
|
||||
protected String password;
|
||||
protected String path;
|
||||
protected Random random;
|
||||
|
||||
public Student(String name, String password, String path) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.path = path;
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成有效的括号位置
|
||||
* 确保括号不会包围整个表达式
|
||||
*
|
||||
* @param operands 操作数数量
|
||||
* @return 包含起始和结束位置的数组 [parenStart, parenEnd]
|
||||
*/
|
||||
protected int[] bracketMaker(int operands) {
|
||||
boolean useParen = operands > 2 && random.nextBoolean();
|
||||
int parenStart = 0;
|
||||
int parenEnd = operands - 1;
|
||||
|
||||
while (parenStart == 0 && parenEnd == operands - 1) {
|
||||
parenStart = useParen ? random.nextInt(operands - 1) : -2;
|
||||
parenEnd = useParen ? random.nextInt(operands - 1 - parenStart) + parenStart + 1 : -2;
|
||||
}
|
||||
|
||||
return new int[]{parenStart, parenEnd};
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机选择特殊操作符的位置
|
||||
*
|
||||
* @param operands 操作数数量
|
||||
* @return 标记特殊操作符位置的布尔数组
|
||||
*/
|
||||
protected boolean[] randomMaker(int operands) {
|
||||
int specialNumber = Math.min(operands, random.nextInt(operands) + 1);
|
||||
boolean[] specialOpFlags = new boolean[operands];
|
||||
|
||||
for (int i = 0; i < specialNumber; i++) {
|
||||
int pos;
|
||||
do {
|
||||
pos = random.nextInt(operands);
|
||||
} while (specialOpFlags[pos]);
|
||||
specialOpFlags[pos] = true;
|
||||
}
|
||||
|
||||
return specialOpFlags;
|
||||
}
|
||||
|
||||
protected abstract String makeOneQuestion();
|
||||
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
package ui;
|
||||
|
||||
import model.UserManager;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 修改密码对话框
|
||||
* 用户在登录状态下可以修改密码
|
||||
*/
|
||||
public class ChangePasswordDialog extends JDialog {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Pattern PASSWORD_PATTERN =
|
||||
Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{6,10}$");
|
||||
|
||||
private final JPasswordField oldPasswordField;
|
||||
private final JPasswordField newPassword1Field;
|
||||
private final JPasswordField newPassword2Field;
|
||||
private final JButton confirmButton;
|
||||
private final UserManager userManager;
|
||||
private final String email;
|
||||
|
||||
/**
|
||||
* 构造修改密码对话框
|
||||
*
|
||||
* @param parent 父窗口
|
||||
* @param email 用户邮箱
|
||||
*/
|
||||
public ChangePasswordDialog(Frame parent, String email) {
|
||||
super(parent, "修改密码", true);
|
||||
this.email = email;
|
||||
this.userManager = new UserManager();
|
||||
|
||||
setSize(600, 360);
|
||||
setLocationRelativeTo(parent);
|
||||
setResizable(true);
|
||||
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.insets = new Insets(5, 5, 5, 5);
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
JLabel infoLabel = new JLabel("<html>新密码要求:<br>" +
|
||||
"1. 长度 6-10位<br>" +
|
||||
"2. 必须包含大写字母<br>" +
|
||||
"3. 必须包含小写字母<br>" +
|
||||
"4. 必须包含数字</html>");
|
||||
infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 11));
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.gridwidth = 2;
|
||||
panel.add(infoLabel, gbc);
|
||||
|
||||
gbc.gridwidth = 1;
|
||||
gbc.gridy = 1;
|
||||
panel.add(new JLabel("原密码:"), gbc);
|
||||
|
||||
oldPasswordField = new JPasswordField(20);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(oldPasswordField, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
panel.add(new JLabel("新密码:"), gbc);
|
||||
|
||||
newPassword1Field = new JPasswordField(20);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(newPassword1Field, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 3;
|
||||
panel.add(new JLabel("确认新密码:"), gbc);
|
||||
|
||||
newPassword2Field = new JPasswordField(20);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(newPassword2Field, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
confirmButton = new JButton("确认修改");
|
||||
confirmButton.setPreferredSize(new Dimension(120, 30));
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 4;
|
||||
gbc.gridwidth = 2;
|
||||
gbc.anchor = GridBagConstraints.CENTER;
|
||||
panel.add(confirmButton, gbc);
|
||||
|
||||
add(panel);
|
||||
|
||||
confirmButton.addActionListener(e -> handleConfirm());
|
||||
getRootPane().setDefaultButton(confirmButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理确认修改
|
||||
*/
|
||||
private void handleConfirm() {
|
||||
String oldPassword = new String(oldPasswordField.getPassword());
|
||||
String newPassword1 = new String(newPassword1Field.getPassword());
|
||||
String newPassword2 = new String(newPassword2Field.getPassword());
|
||||
|
||||
if (oldPassword.isEmpty() || newPassword1.isEmpty() ||
|
||||
newPassword2.isEmpty()) {
|
||||
showError("所有字段都不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newPassword1.equals(newPassword2)) {
|
||||
showError("两次输入的新密码不一致");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PASSWORD_PATTERN.matcher(newPassword1).matches()) {
|
||||
showError("新密码不符合要求:\n" +
|
||||
"长度6-10位, 必须包含大小写字母和数字");
|
||||
return;
|
||||
}
|
||||
|
||||
if (userManager.changePassword(email, oldPassword, newPassword1)) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"密码修改成功!",
|
||||
"成功",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
dispose();
|
||||
} else {
|
||||
showError("原密码错误");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示错误信息
|
||||
*
|
||||
* @param message 错误消息
|
||||
*/
|
||||
private void showError(String message) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
message,
|
||||
"错误",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package ui;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* 数学学习软件主入口
|
||||
*
|
||||
* @author 结对项目
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MathLearningApp {
|
||||
|
||||
/**
|
||||
* 程序主入口
|
||||
*
|
||||
* @param args 命令行参数
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
LoginFrame loginFrame = new LoginFrame();
|
||||
loginFrame.setVisible(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,215 @@
|
||||
package ui;
|
||||
|
||||
import model.Grade;
|
||||
import model.UserManager;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.io.Serial;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 密码设置对话框
|
||||
* 用于新用户注册时设置密码和选择年级
|
||||
*/
|
||||
public class PasswordSetupDialog extends JDialog {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Pattern PASSWORD_PATTERN =
|
||||
Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z0-9]{6,10}$");
|
||||
|
||||
private final JTextField usernameField;
|
||||
private final JPasswordField password1Field;
|
||||
private final JPasswordField password2Field;
|
||||
private final JComboBox<String> gradeComboBox;
|
||||
private final JButton confirmButton;
|
||||
private final UserManager userManager;
|
||||
private final String email;
|
||||
private boolean registrationComplete;
|
||||
|
||||
/**
|
||||
* 构造密码设置对话框
|
||||
*
|
||||
* @param parent 父窗口
|
||||
* @param userManager 用户管理器
|
||||
* @param email 用户邮箱
|
||||
*/
|
||||
public PasswordSetupDialog(Frame parent, UserManager userManager, String email) {
|
||||
super(parent, "设置密码和用户名", true);
|
||||
this.userManager = userManager;
|
||||
this.email = email;
|
||||
this.registrationComplete = false;
|
||||
|
||||
setSize(600, 420);
|
||||
setLocationRelativeTo(parent);
|
||||
setResizable(true);
|
||||
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.insets = new Insets(5, 5, 5, 5);
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
JLabel infoLabel = new JLabel("<html>密码要求:<br>" +
|
||||
"1. 长度 6-10位<br>" +
|
||||
"2. 必须包含大写字母<br>" +
|
||||
"3. 必须包含小写字母<br>" +
|
||||
"4. 必须包含数字<br>" +
|
||||
"5. 不能包含其他特殊字符</html>");
|
||||
infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 11));
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.gridwidth = 2;
|
||||
panel.add(infoLabel, gbc);
|
||||
|
||||
gbc.gridwidth = 1;
|
||||
gbc.gridy = 1;
|
||||
panel.add(new JLabel("输入密码:"), gbc);
|
||||
|
||||
password1Field = new JPasswordField(20);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(password1Field, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
panel.add(new JLabel("确认密码:"), gbc);
|
||||
|
||||
password2Field = new JPasswordField(20);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(password2Field, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 3;
|
||||
panel.add(new JLabel("设置用户名:"), gbc);
|
||||
|
||||
usernameField = new JTextField(20);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(usernameField, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 4;
|
||||
panel.add(new JLabel("选择年级:"), gbc);
|
||||
|
||||
String[] grades = {"小学", "初中", "高中"};
|
||||
gradeComboBox = new JComboBox<>(grades);
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1.0;
|
||||
panel.add(gradeComboBox, gbc);
|
||||
gbc.weightx = 0.0;
|
||||
|
||||
confirmButton = new JButton("确认注册");
|
||||
confirmButton.setPreferredSize(new Dimension(120, 30));
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 5;
|
||||
gbc.gridwidth = 2;
|
||||
gbc.anchor = GridBagConstraints.CENTER;
|
||||
panel.add(confirmButton, gbc);
|
||||
|
||||
add(panel);
|
||||
|
||||
confirmButton.addActionListener(e -> handleConfirm());
|
||||
getRootPane().setDefaultButton(confirmButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理确认注册
|
||||
*/
|
||||
private void handleConfirm() {
|
||||
String password1 = new String(password1Field.getPassword());
|
||||
String password2 = new String(password2Field.getPassword());
|
||||
String username = usernameField.getText().trim();
|
||||
|
||||
if (username.isEmpty() || password1.isEmpty() || password2.isEmpty()) {
|
||||
showError("用户名和密码不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
if (userManager.usernameExists(username)) {
|
||||
showError("该用户名已被使用,请更换一个");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password1.equals(password2)) {
|
||||
showError("两次输入的密码不一致");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PASSWORD_PATTERN.matcher(password1).matches()) {
|
||||
showError("密码不符合要求:\n" +
|
||||
"长度6-10位, 必须包含大小写字母和数字, 且不能包含特殊字符");
|
||||
return;
|
||||
}
|
||||
|
||||
Grade gradeType = getSelectedGradeType();
|
||||
boolean success = userManager.register(email, password1, gradeType, username);
|
||||
|
||||
if (success) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"注册成功!请返回登录。",
|
||||
"成功",
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
registrationComplete = true;
|
||||
dispose();
|
||||
} else {
|
||||
showError("注册失败,该邮箱可能已被注册");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选择的年级类型
|
||||
*
|
||||
* @return 年级类型
|
||||
*/
|
||||
private Grade getSelectedGradeType() {
|
||||
String selected = (String) gradeComboBox.getSelectedItem();
|
||||
switch (selected) {
|
||||
case "小学":
|
||||
return Grade.primary;
|
||||
case "初中":
|
||||
return Grade.middle;
|
||||
case "高中":
|
||||
return Grade.high;
|
||||
default:
|
||||
return Grade.primary;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示错误信息
|
||||
*
|
||||
* @param message 错误消息
|
||||
*/
|
||||
private void showError(String message) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
message,
|
||||
"错误",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查注册是否完成
|
||||
*
|
||||
* @return 注册是否完成
|
||||
*/
|
||||
public boolean isRegistrationComplete() {
|
||||
return registrationComplete;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,208 @@
|
||||
package ui;
|
||||
|
||||
import model.Grade;
|
||||
import model.Question;
|
||||
import model.QuestionMaker;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.io.Serial;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 答题界面
|
||||
* 显示题目和选项,接收用户答案
|
||||
*/
|
||||
public class QuizFrame extends JFrame {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String email;
|
||||
private final Grade gradeType;
|
||||
private final List<Question> questions;
|
||||
private int currentIndex;
|
||||
private int correctCount;
|
||||
|
||||
private JLabel questionLabel;
|
||||
private JLabel progressLabel;
|
||||
private JRadioButton[] optionButtons;
|
||||
private JButton submitButton;
|
||||
|
||||
/**
|
||||
* 构造答题界面
|
||||
*
|
||||
* @param email 用户邮箱
|
||||
* @param gradeType 年级类型
|
||||
* @param questionCount 题目数量
|
||||
*/
|
||||
public QuizFrame(String email, Grade gradeType, int questionCount) {
|
||||
this.email = email;
|
||||
this.gradeType = gradeType;
|
||||
this.currentIndex = 0;
|
||||
this.correctCount = 0;
|
||||
|
||||
QuestionMaker generator = new QuestionMaker();
|
||||
this.questions = generator.makeQuestions(gradeType, questionCount, email);
|
||||
|
||||
if (questions.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"生成题目失败,返回主界面",
|
||||
"错误",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
returnToGradeSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
setTitle("数学学习软件 - 答题");
|
||||
setSize(900, 600);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setLocationRelativeTo(null);
|
||||
setResizable(true);
|
||||
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
|
||||
progressLabel = new JLabel("", JLabel.CENTER);
|
||||
progressLabel.setFont(new Font("微软雅黑", Font.BOLD, 14));
|
||||
mainPanel.add(progressLabel, BorderLayout.NORTH);
|
||||
|
||||
JPanel centerPanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.insets = new Insets(10, 10, 10, 10);
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
// 新增:答案格式提示
|
||||
JLabel answerFormatLabel = new JLabel("注意:所有计算结果的答案均保留两位小数。", JLabel.CENTER);
|
||||
answerFormatLabel.setFont(new Font("微软雅黑", Font.ITALIC, 12));
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.gridwidth = 2;
|
||||
centerPanel.add(answerFormatLabel, gbc);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 1;
|
||||
gbc.gridwidth = 2;
|
||||
|
||||
questionLabel = new JLabel();
|
||||
questionLabel.setFont(new Font("Cambria Math", Font.PLAIN, 18));
|
||||
questionLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10));
|
||||
centerPanel.add(questionLabel, gbc);
|
||||
|
||||
ButtonGroup optionGroup = new ButtonGroup();
|
||||
optionButtons = new JRadioButton[4];
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
optionButtons[i] = new JRadioButton();
|
||||
optionButtons[i].setFont(new Font("Cambria Math", Font.PLAIN, 14));
|
||||
optionGroup.add(optionButtons[i]);
|
||||
gbc.gridy = i + 2;
|
||||
gbc.gridwidth = 2;
|
||||
centerPanel.add(optionButtons[i], gbc);
|
||||
gbc.gridwidth = 1;
|
||||
}
|
||||
|
||||
mainPanel.add(centerPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
|
||||
submitButton = new JButton("提交答案");
|
||||
submitButton.setPreferredSize(new Dimension(150, 35));
|
||||
submitButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
|
||||
bottomPanel.add(submitButton);
|
||||
|
||||
mainPanel.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
add(mainPanel);
|
||||
|
||||
submitButton.addActionListener(e -> handleSubmit());
|
||||
|
||||
displayQuestion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示当前题目
|
||||
*/
|
||||
private void displayQuestion() {
|
||||
if (currentIndex >= questions.size()) {
|
||||
showResult();
|
||||
return;
|
||||
}
|
||||
|
||||
Question question = questions.get(currentIndex);
|
||||
progressLabel.setText(String.format("第 %d/%d 题",
|
||||
currentIndex + 1, questions.size()));
|
||||
questionLabel.setText("<html><body style='width: 500px'>" +
|
||||
question.getQuestionText() + "</body></html>");
|
||||
|
||||
String[] options = question.getOptions();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
optionButtons[i].setText(options[i]);
|
||||
optionButtons[i].setSelected(false);
|
||||
}
|
||||
|
||||
submitButton.setEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理答案提交
|
||||
*/
|
||||
private void handleSubmit() {
|
||||
int selectedIndex = -1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (optionButtons[i].isSelected()) {
|
||||
selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIndex == -1) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"请选择一个答案",
|
||||
"提示",
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
Question question = questions.get(currentIndex);
|
||||
if (selectedIndex == question.getCorrectAnswer()) {
|
||||
correctCount++;
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
displayQuestion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示答题结果
|
||||
*/
|
||||
private void showResult() {
|
||||
double percentage = (double) correctCount / questions.size() * 100;
|
||||
int score = (int) percentage;
|
||||
|
||||
ResultFrame resultFrame = new ResultFrame(
|
||||
email, gradeType, score, correctCount, questions.size());
|
||||
resultFrame.setVisible(true);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回年级选择界面
|
||||
*/
|
||||
private void returnToGradeSelection() {
|
||||
GradeSelectionFrame frame = new GradeSelectionFrame(email, gradeType);
|
||||
frame.setVisible(true);
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,127 @@
|
||||
package ui;
|
||||
|
||||
import model.Grade;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
|
||||
/**
|
||||
* 答题结果展示界面
|
||||
* 显示得分和统计信息,提供继续答题或退出选项
|
||||
*/
|
||||
public class ResultFrame extends JFrame {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String email;
|
||||
private final Grade gradeType;
|
||||
|
||||
/**
|
||||
* 构造结果展示界面
|
||||
*
|
||||
* @param email 用户邮箱
|
||||
* @param gradeType 年级类型
|
||||
* @param score 得分
|
||||
* @param correctCount 答对题数
|
||||
* @param totalCount 总题数
|
||||
*/
|
||||
public ResultFrame(String email, Grade gradeType, int score,
|
||||
int correctCount, int totalCount) {
|
||||
this.email = email;
|
||||
this.gradeType = gradeType;
|
||||
|
||||
setTitle("数学学习软件 - 答题结果");
|
||||
setSize(600, 420);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setLocationRelativeTo(null);
|
||||
setResizable(true);
|
||||
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
|
||||
|
||||
JPanel centerPanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.insets = new Insets(10, 10, 10, 10);
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
|
||||
JLabel titleLabel = new JLabel("答题完成!", JLabel.CENTER);
|
||||
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
|
||||
centerPanel.add(titleLabel, gbc);
|
||||
|
||||
gbc.gridy = 1;
|
||||
JLabel scoreLabel = new JLabel("得分: " + score, JLabel.CENTER);
|
||||
scoreLabel.setFont(new Font("微软雅黑", Font.BOLD, 36));
|
||||
scoreLabel.setForeground(getScoreColor(score));
|
||||
centerPanel.add(scoreLabel, gbc);
|
||||
|
||||
gbc.gridy = 2;
|
||||
JLabel detailLabel = new JLabel(
|
||||
String.format("答对 %d 题 / 共 %d 题", correctCount, totalCount),
|
||||
JLabel.CENTER);
|
||||
detailLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
||||
centerPanel.add(detailLabel, gbc);
|
||||
|
||||
mainPanel.add(centerPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 0));
|
||||
JButton continueButton = new JButton("继续做题");
|
||||
JButton exitButton = new JButton("退出");
|
||||
|
||||
continueButton.setPreferredSize(new Dimension(120, 35));
|
||||
exitButton.setPreferredSize(new Dimension(120, 35));
|
||||
|
||||
buttonPanel.add(continueButton);
|
||||
buttonPanel.add(exitButton);
|
||||
|
||||
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
add(mainPanel);
|
||||
|
||||
continueButton.addActionListener(e -> continueQuiz());
|
||||
exitButton.addActionListener(e -> exitToSelection());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分数返回对应颜色
|
||||
*
|
||||
* @param score 分数
|
||||
* @return 颜色对象
|
||||
*/
|
||||
private Color getScoreColor(int score) {
|
||||
if (score >= 90) {
|
||||
return new Color(0, 150, 0);
|
||||
} else if (score >= 60) {
|
||||
return new Color(255, 140, 0);
|
||||
} else {
|
||||
return new Color(200, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 继续做题
|
||||
*/
|
||||
private void continueQuiz() {
|
||||
GradeSelectionFrame frame = new GradeSelectionFrame(email, gradeType);
|
||||
frame.setVisible(true);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出到选择界面
|
||||
*/
|
||||
private void exitToSelection() {
|
||||
GradeSelectionFrame frame = new GradeSelectionFrame(email, gradeType);
|
||||
frame.setVisible(true);
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
package ui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* 用户设置对话框
|
||||
* 显示用户信息并提供修改密码的入口
|
||||
*/
|
||||
public class UserSettingsDialog extends JDialog {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String email;
|
||||
private final String username;
|
||||
private final Frame parentFrame;
|
||||
|
||||
/**
|
||||
* 构造用户设置对话框
|
||||
*
|
||||
* @param parent 父窗口
|
||||
* @param email 用户邮箱
|
||||
* @param username 用户名
|
||||
*/
|
||||
public UserSettingsDialog(Frame parent, String email, String username) {
|
||||
super(parent, "用户设置", true);
|
||||
this.parentFrame = parent;
|
||||
this.email = email;
|
||||
this.username = username;
|
||||
|
||||
setSize(400, 250);
|
||||
setLocationRelativeTo(parent);
|
||||
setResizable(false);
|
||||
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.insets = new Insets(10, 5, 10, 5);
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
|
||||
// 显示用户名
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
panel.add(new JLabel("用户名:"), gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
JLabel usernameLabel = new JLabel(username);
|
||||
usernameLabel.setFont(new Font("微软雅黑", Font.BOLD, 14));
|
||||
panel.add(usernameLabel, gbc);
|
||||
|
||||
// 显示邮箱
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 1;
|
||||
panel.add(new JLabel("邮箱:"), gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
JLabel emailLabel = new JLabel(email);
|
||||
emailLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
||||
panel.add(emailLabel, gbc);
|
||||
|
||||
// 修改密码按钮
|
||||
JButton changePasswordButton = new JButton("修改密码");
|
||||
changePasswordButton.setPreferredSize(new Dimension(120, 30));
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 2;
|
||||
gbc.gridwidth = 2;
|
||||
gbc.anchor = GridBagConstraints.CENTER;
|
||||
gbc.insets = new Insets(20, 5, 10, 5);
|
||||
panel.add(changePasswordButton, gbc);
|
||||
|
||||
add(panel);
|
||||
|
||||
// 按钮点击事件
|
||||
changePasswordButton.addActionListener(e -> openChangePasswordDialog());
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开修改密码对话框
|
||||
*/
|
||||
private void openChangePasswordDialog() {
|
||||
// 关闭当前对话框
|
||||
this.dispose();
|
||||
// 打开修改密码对话框
|
||||
ChangePasswordDialog dialog = new ChangePasswordDialog(parentFrame, email);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"1617940512@qq.com": {
|
||||
"email": "1617940512@qq.com",
|
||||
"password": "Qwerty1",
|
||||
"grade": "primary",
|
||||
"username": "zhang"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue