Swing小项目
无需任何额外配置,直接可以在eclipse用
非常简单的文件结构
简单的登录界面
进去后就大概是这么个样子
很久以前写的了,我就不一一打开展示了。内容和无UI版本差不多,只是用简单的Swing实现了界面化操作
数据是可以保存在根目录下的data.bat文件中,退出重新登录,之前录入的数据也是存在的。
Main.java
package swing;import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;public class Main {private static final String FILE_PATH = "data.dat";//static修饰符表示变量FILE_PATH是类级别的,而不是实例(对象)级别的。即不需要创建Main类的对象就可以访问FILE_PATH,否则需要通过Main类的对象来访问,final修饰符表示变量初始化后就无法更改private static List<Course> courseList = new ArrayList<>();private static List<Teacher> teacherList = new ArrayList<>();private static List<Student> studentList = new ArrayList<>();public static void main(String[] args) {loadData();SwingUtilities.invokeLater(() -> {new LoginFrame();});} public static void loadData() {try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.dat"))) {courseList = (List<Course>) ois.readObject();//读取是反序列化的过程,将文件存储的字节流提取出来还原到对象中teacherList = (List<Teacher>) ois.readObject();studentList = (List<Student>) ois.readObject();JOptionPane.showMessageDialog(null, "Data loaded successfully.");} catch (EOFException e) {JOptionPane.showMessageDialog(null, "Data file not found, initializing default data.");} catch (Exception e) {e.printStackTrace();}}public static void saveData() {try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.dat"))) {oos.writeObject(courseList);//写入是序列化的过程,将数据转化为字节流的形式存储起来oos.writeObject(teacherList);oos.writeObject(studentList);JOptionPane.showMessageDialog(null, "Data saved successfully.");} catch (Exception e) {e.printStackTrace();}}public static List<Course> getCourseList() {return courseList;}public static List<Teacher> getTeacherList() {return teacherList;}public static List<Student> getStudentList() {return studentList;}
}
AdminMenu.java
package swing;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;public class AdminMenu extends JFrame {public AdminMenu() {setTitle("管理员菜单");setSize(600, 400); // 调整窗口大小setLayout(new GridLayout(8, 1));JButton addCourseButton = new JButton("添加课程");JButton deleteCourseButton = new JButton("删除课程");JButton sortCoursesButton = new JButton("按照选课人数排序");JButton modifyTeacherButton = new JButton("修改授课教师");JButton restorePasswordsButton = new JButton("恢复密码");JButton viewListsButton = new JButton("查看课程、教师和学生列表");JButton addTeacherButton = new JButton("添加教师");JButton addStudentButton = new JButton("添加学生");JButton deleteTeacherButton = new JButton("删除教师");JButton deleteStudentButton = new JButton("删除学生");add(addCourseButton);add(deleteCourseButton);add(sortCoursesButton);add(modifyTeacherButton);add(restorePasswordsButton);add(viewListsButton);add(addTeacherButton);add(addStudentButton);add(deleteTeacherButton);add(deleteStudentButton);addCourseButton.addActionListener(e -> addCourse());deleteCourseButton.addActionListener(e -> deleteCourse());sortCoursesButton.addActionListener(e -> sortCourses());modifyTeacherButton.addActionListener(e -> modifyTeacher());restorePasswordsButton.addActionListener(e -> restorePasswords());viewListsButton.addActionListener(e -> viewLists());addTeacherButton.addActionListener(e -> addTeacher());addStudentButton.addActionListener(e -> addStudent());deleteTeacherButton.addActionListener(e -> deleteTeacher());deleteStudentButton.addActionListener(e -> deleteStudent());setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);}private void addCourse() {String courseName = JOptionPane.showInputDialog("输入课程名称:");String isMandatoryInput = JOptionPane.showInputDialog("输入是否为必修课 (yes/no):");boolean isMandatory = isMandatoryInput.equalsIgnoreCase("yes");Teacher selectedTeacher = (Teacher) JOptionPane.showInputDialog(null, "选择任课教师:", "添加课程", JOptionPane.QUESTION_MESSAGE, null, Main.getTeacherList().toArray(), Main.getTeacherList().get(0));Course newCourse = new Course(courseName, isMandatory, selectedTeacher);if (!isMandatory) {String maxEnrollmentInput = JOptionPane.showInputDialog("输入最大选课人数:");newCourse.maxEnrollment = Integer.parseInt(maxEnrollmentInput); // 仅对选修课设置最大人数}Main.getCourseList().add(newCourse);Main.saveData();JOptionPane.showMessageDialog(this, "课程添加成功");}private void deleteCourse() {String courseName = JOptionPane.showInputDialog("输入要删除的课程名称:");Main.getCourseList().removeIf(course -> course.getName().equals(courseName));Main.saveData();JOptionPane.showMessageDialog(this, "课程删除成功");}private void sortCourses() {Main.getCourseList().sort(Comparator.comparingInt(Course::getCurrentEnrollment).reversed());JOptionPane.showMessageDialog(this, "课程已按选课人数排序");}private void modifyTeacher() {String teacherName = JOptionPane.showInputDialog("输入教师用户名:");String newCourseName = JOptionPane.showInputDialog("输入新的课程名称:");// 修改授课教师的逻辑// 这里可以扩展,以便选择具体的课程和教师进行修改JOptionPane.showMessageDialog(this, "授课教师修改成功");}private void restorePasswords() {for (Teacher teacher : Main.getTeacherList()) {teacher.changePassword("123456");}for (Student student : Main.getStudentList()) {student.changePassword("123456");}Main.saveData();JOptionPane.showMessageDialog(this, "所有密码已恢复为初始密码");}private void viewLists() { StringBuilder list = new StringBuilder("课程列表:\n");for (Course course : Main.getCourseList()) {String courseType = course.getCourseType(); // 获取课程类型String teacherName = course.getTeacher().getUsername(); // 获取任课教师String enrollmentInfo = course.isMandatory() ? "" : ", 选课人数: " + course.getCurrentEnrollment() + "/" + course.getMaxEnrollment();list.append(String.format("课程名称: %s, 类型: %s, 任课教师: %s%s\n", course.getName(), courseType, teacherName, enrollmentInfo));}list.append("教师列表:\n");for (Teacher teacher : Main.getTeacherList()) {list.append(teacher.getUsername()).append("\n");}list.append("学生列表:\n");for (Student student : Main.getStudentList()) {list.append(student.getUsername()).append("\n");}JOptionPane.showMessageDialog(this, list.toString());}private void addTeacher() {String teacherName = JOptionPane.showInputDialog("输入教师用户名:");String teacherPassword = "123456"; // 默认密码Teacher newTeacher = new Teacher(teacherName, teacherPassword);Main.getTeacherList().add(newTeacher);Main.saveData();JOptionPane.showMessageDialog(this, "教师添加成功");}private void addStudent() {String studentName = JOptionPane.showInputDialog("输入学生用户名:");String studentPassword = "123456"; // 默认密码Student newStudent = new Student(studentName, studentPassword);Main.getStudentList().add(newStudent);Main.saveData();JOptionPane.showMessageDialog(this, "学生添加成功");}private void deleteTeacher() {String teacherName = JOptionPane.showInputDialog("输入要删除的教师用户名:");Main.getTeacherList().removeIf(teacher -> teacher.getUsername().equals(teacherName));Main.saveData();JOptionPane.showMessageDialog(this, "教师删除成功");}private void deleteStudent() {String studentName = JOptionPane.showInputDialog("输入要删除的学生用户名:");Main.getStudentList().removeIf(student -> student.getUsername().equals(studentName));Main.saveData();JOptionPane.showMessageDialog(this, "学生删除成功");}
}
Course.java
package swing;import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;public class Course implements Serializable {private static final long serialVersionUID = 1L;private String name;private boolean isMandatory; // true表示必修课protected int maxEnrollment; // 最大选课人数,选修课时有效private List<Student> enrolledStudents;private Teacher teacher;public Course(String name, boolean isMandatory, Teacher teacher) {this.name = name;this.isMandatory = isMandatory;this.enrolledStudents = new ArrayList<>();this.teacher = teacher;this.maxEnrollment = isMandatory ? Integer.MAX_VALUE : 30; // 选修课默认最大人数}public String getName() {return name;}public boolean isMandatory() {return isMandatory;}public int getCurrentEnrollment() {return enrolledStudents.size();}public List<Student> getEnrolledStudents() {return enrolledStudents;}public Teacher getTeacher() {return teacher;}public void enrollStudent(Student student) {if (isMandatory || enrolledStudents.size() < maxEnrollment) {enrolledStudents.add(student);}}public String getCourseType() {return isMandatory ? "必修课" : "选修课";}public int getMaxEnrollment() {return maxEnrollment;}
}
LoginFrame.java
package swing;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class LoginFrame extends JFrame {private static final long serialVersionUID = 1L; // 添加serialVersionUIDprivate JTextField usernameField;private JPasswordField passwordField;private JButton togglePasswordButton;public LoginFrame() {setTitle("登录");setSize(300, 150);setLayout(new GridLayout(3, 2));add(new JLabel("用户名:"));usernameField = new JTextField();add(usernameField);add(new JLabel("密码:"));passwordField = new JPasswordField();add(passwordField);togglePasswordButton = new JButton("显示密码");add(togglePasswordButton);JButton loginButton = new JButton("登录");add(loginButton);loginButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {login();}});// Add action listener for the buttontogglePasswordButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {togglePasswordVisibility();}});setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);}private void togglePasswordVisibility() {// 检查密码框当前的回显字符模式if (passwordField.getEchoChar() == '\u0000') { // '\u0000' 表示没有字符被回显(密码可见)passwordField.setEchoChar('*'); // 重置回显字符为 '*',隐藏密码togglePasswordButton.setText("显示密码");} else {passwordField.setEchoChar((char) 0); // 设置回显字符为 0,使密码明文显示togglePasswordButton.setText("隐藏密码");}
}private void login() {String username = usernameField.getText();String password = new String(passwordField.getPassword());if (username.equals("admin") && password.equals("admin123")) {new AdminMenu();dispose();} else {// Check other user typesfor (Teacher teacher : Main.getTeacherList()) {if (teacher.getUsername().equals(username) && teacher.getPassword().equals(password)) {new TeacherMenu(teacher);dispose();return;}}for (Student student : Main.getStudentList()) {if (student.getUsername().equals(username) && student.getPassword().equals(password)) {new StudentMenu(student);dispose();return;}}JOptionPane.showMessageDialog(this, "用户名或密码错误");}}
}
Student.java
package swing;import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;public class Student implements Serializable {private String username;private String password;private List<Course> selectedCourses; // 存储所选课程的列表public Student(String username, String password) {this.username = username;this.password = password;this.selectedCourses = new ArrayList<>(); // 初始化课程列表}// Getter方法public String getUsername() {return username;}public String getPassword() {return password;}public List<Course> getSelectedCourses() {return selectedCourses;}public void addCourse(Course course) {if (!selectedCourses.contains(course)) {selectedCourses.add(course);}}// 修改密码的方法public void changePassword(String newPassword) {this.password = newPassword;}// 重写 toString() 方法@Overridepublic String toString() {return username; // 返回学生的用户名}
}
StudentMenu.java
package swing;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class StudentMenu extends JFrame {private static final long serialVersionUID = 1L;private Student student;public StudentMenu(Student student) {this.student = student;setTitle("学生菜单");setSize(400, 300);setLayout(new GridLayout(4, 1));JButton changePasswordButton = new JButton("修改密码");JButton viewCoursesButton = new JButton("查看所上课程");JButton enrollButton = new JButton("选修课程");add(changePasswordButton);add(viewCoursesButton);add(enrollButton);changePasswordButton.addActionListener(e -> changePassword());viewCoursesButton.addActionListener(e -> viewCourses());enrollButton.addActionListener(e -> enrollCourse());setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);}private void changePassword() {String newPassword = JOptionPane.showInputDialog("输入新密码:");student.changePassword(newPassword);Main.saveData();JOptionPane.showMessageDialog(this, "密码已修改");}private void viewCourses() {StringBuilder courseList = new StringBuilder("所上课程:\n");// 添加必修课程for (Course course : Main.getCourseList()) {if (course.isMandatory()) {courseList.append(course.getName()).append(" - 任课教师: ").append(course.getTeacher().getUsername()).append("\n");}}// 添加选修课程for (Course course : student.getSelectedCourses()) {courseList.append(course.getName()).append(" - 任课教师: ").append(course.getTeacher().getUsername()).append("\n");}JOptionPane.showMessageDialog(this, courseList.toString());}private void enrollCourse() {String courseName = JOptionPane.showInputDialog("输入要选修的课程名称:");for (Course course : Main.getCourseList()) {if (course.getName().equals(courseName)) {// 验证选课人数if (course.isMandatory() || course.getCurrentEnrollment() < course.getMaxEnrollment()) {selectElectiveCourse(course);return;} else {JOptionPane.showMessageDialog(this, "课程已满");}}}JOptionPane.showMessageDialog(this, "课程不存在");}// 选修课程的方法private void selectElectiveCourse(Course course) {if (!course.isMandatory()) {student.addCourse(course); // 将选修课程添加到学生的课程列表中JOptionPane.showMessageDialog(this, "选修课程成功!");Main.saveData(); // 保存数据}}
}
Teacher.java
package swing;import java.io.Serializable;public class Teacher implements Serializable {private String username;private String password;public Teacher(String username, String password) {this.username = username;this.password = password;}// Getter方法public String getUsername() {return username;}public String getPassword() {return password;}// 修改密码的方法public void changePassword(String newPassword) {this.password = newPassword;}// 重写 toString() 方法@Overridepublic String toString() {return username; // 返回教师的用户名}
}
TeacherMenu.java
package swing;import javax.swing.*;
import java.awt.*;public class TeacherMenu extends JFrame {private static final long serialVersionUID = 1L;private Teacher teacher;public TeacherMenu(Teacher teacher) {this.teacher = teacher;setTitle("教师菜单");setSize(400, 300);setLayout(new GridLayout(5, 1)); // 增加一行JButton changePasswordButton = new JButton("修改密码");JButton viewCoursesButton = new JButton("查看所授课程");JButton viewStudentsButton = new JButton("查看上课学生");JButton viewCourseStudentsButton = new JButton("查看某门课程的学生");add(changePasswordButton);add(viewCoursesButton);add(viewStudentsButton);add(viewCourseStudentsButton);changePasswordButton.addActionListener(e -> changePassword());viewCoursesButton.addActionListener(e -> viewCourses());viewStudentsButton.addActionListener(e -> viewStudentsInCourses());viewCourseStudentsButton.addActionListener(e -> viewStudentsInSpecificCourse());setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setVisible(true);}private void changePassword() {String newPassword = JOptionPane.showInputDialog("输入新密码:");teacher.changePassword(newPassword);Main.saveData();JOptionPane.showMessageDialog(this, "密码已修改");}private void viewCourses() {StringBuilder mandatoryCourses = new StringBuilder("必修课:\n");StringBuilder electiveCourses = new StringBuilder("选修课:\n");for (Course course : Main.getCourseList()) {if (course.isMandatory()) {mandatoryCourses.append(String.format("课程名称: %s, 任课教师: %s\n", course.getName(), course.getTeacher().getUsername()));} else {electiveCourses.append(String.format("课程名称: %s, 任课教师: %s, 选课人数: %d/%d\n", course.getName(), course.getTeacher().getUsername(), course.getCurrentEnrollment(), course.getMaxEnrollment()));}}StringBuilder courseListDisplay = new StringBuilder();courseListDisplay.append(mandatoryCourses).append("\n").append(electiveCourses);JOptionPane.showMessageDialog(this, courseListDisplay.toString());}private void viewStudentsInCourses() {StringBuilder studentList = new StringBuilder("上课学生名单:\n");boolean hasCourses = false;for (Course course : Main.getCourseList()) {if (course.getTeacher().equals(teacher)) {hasCourses = true;studentList.append("课程: ").append(course.getName()).append("\n");for (Student student : course.getEnrolledStudents()) {studentList.append(" - ").append(student.getUsername()).append("\n");}}}if (!hasCourses) {studentList.append("该教师没有教授任何课程。");}JOptionPane.showMessageDialog(this, studentList.toString());}private void viewStudentsInSpecificCourse() {String courseName = JOptionPane.showInputDialog("输入课程名称:");StringBuilder studentList = new StringBuilder("学生名单:\n");boolean foundCourse = false;for (Course course : Main.getCourseList()) {if (course.getName().equals(courseName) && course.getTeacher().equals(teacher)) {foundCourse = true;for (Student student : course.getEnrolledStudents()) {studentList.append(student.getUsername()).append("\n");}break;}}if (!foundCourse) {studentList.append("没有找到该课程或该课程不属于您。");}JOptionPane.showMessageDialog(this, studentList.toString());}
}
module-info.java
module experiment_2 {requires java.desktop;
}