Java实训项目笔记(学生管理系统)

(三)、《学生管理项目》设计

1、完成效果图

image-20210707172303378

2、完整的代码

- SchoolClassDAO.java
package org.ngweb.student.dao;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.ngweb.student.model.SchoolClass;

public class SchoolClassDAO {
	//1. 私有变量,保存的文件名
	private String fileName;
	//2. 初始化文件名
	public SchoolClassDAO(String fileName) {
		this.fileName = fileName;
	}
	//save方法:保存
	public void save(SchoolClass schoolClass) {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream(fileName));
			oos.writeObject(schoolClass);
			oos.close();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	//read方法:读取
	public SchoolClass read() {
		//保存读取的class
		SchoolClass schoolClass = null;
		try {
			ObjectInputStream ois = new ObjectInputStream(
					new FileInputStream(fileName));
			schoolClass = (SchoolClass)ois.readObject();
			ois.close();
		}catch(Exception e) {
			e.printStackTrace();
		}
		return schoolClass;
	}
}

-IPerson.java
package org.ngweb.student.model.interfaze;

import java.io.Serializable;

import org.ngweb.student.model.ValidatorException;

public interface IPerson extends Serializable{
	//从Person中复制的get\set方法体,由于这里不能有方法体,所以删除方法体,得到抽象类。
	public String getId();
	public void setId(String id);
	public String getName();
	public void setName(String name)throws ValidatorException;
	public int getAge();
	public void setAge(int age)throws ValidatorException;
	public String getEmail();
	public void setEmail(String email)throws ValidatorException;
}

- Person.java
package org.ngweb.student.model;
//6. 导入UUID包
import java.util.UUID;
import java.util.regex.*;

import org.ngweb.student.model.interfaze.IPerson;

//1. Person是实现IPerson的所以implements
public class Person implements IPerson {
	//2. 设置每个人的属性,为私有private
	
	private String id;
	private String name;
	private int age;
	private String email;
	
	//4. 构造方法:
	//5. ID:唯一标识符,使用UUID:全球唯一标识码
	public Person() {
		id = UUID.randomUUID().toString();
		this.age=0;
	}
	
	public Person(String name, int age,String email) throws ValidatorException {
		this();
		//7. this()来调用自己的构造方法
		//11. 直接赋值改为set赋值
		setName(name);
		setAge(age);
		setEmail(email);
	}
	
	//3. 自动加上get、set
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) throws ValidatorException {
		//13:	public void setName(String name) throws ValidatorException
		//13.1:声明抛出异常,出现错误原因:set这个方法应该是从IPerson继承来的,IPerson
		//里的set方法没有抛出更多的方法,在实现一个抽象类的时候,实现方法不能比抽象方法抛出更多的异常
		//
		//8.姓名的校验,java的字符36位
		if(name.length()<2 || name.length()>4) {
			this.name = "";//不能为空值
			//12.添加异常处理
			throw new ValidatorException("姓名的长度不符合要求。");
		}
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) throws ValidatorException {
		//9.年龄的校验
		if(age<15 || age>28) {
			this.age = -1;
			throw new ValidatorException("年龄值不符合要求。");
		}
		this.age = age;
	}
	
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) throws ValidatorException {
		//10.对电子邮箱的校验
		Pattern pattern = Pattern
				.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
		Matcher matcher = pattern.matcher(email);
		if(!matcher.matches()) {
			this.email = "";
			throw new ValidatorException("电子邮件格式不对。");
		}
		this.email = email;
	}
}

- SchoolClass.java
package org.ngweb.student.model;

import java.io.Serializable;
import java.util.*;

public class SchoolClass implements Serializable{
	//1. map对象:保存班级的所有学生
	//6. map是无序的,所以采用LinkedHashMap
	private Map<String, Student> map =new LinkedHashMap<String, Student>();

	public Map<String, Student> getMap() {
		return map;
	}

	public void setMap(Map<String, Student> map) {
		this.map = map;
	}
	
	//2. 增删改学生的功能的方法:
	//2.1 增
	public void insertStudent(Student student) {
		map.put(student.getId(), student);
	}
	
	//4. 增加一个方法,用于取得第index位学生
	//4.1:使用的是一个整形参数,用于从map里下标为index的学生
	public Student getStudent(int index) {
		Set<String> set = map.keySet();
		if(index<-1||index>=set.size()) {
			return null;
		}
		Iterator<String> it = set.iterator();
		for(int i=0;i<index;i++) {
			it.next();
		}
		return map.get(it.next());
	}
	//5. 取得班级中的学生
	public int getStudentCount() {
		return map.size();
	}
	
	//2.2 删
	public void deleteStudent(Student student) {
		map.remove(student.getId());
	}
	//2.3 更新
	public void updateStudent(Student student) {
		map.put(student.getId(), student);
	}
	//2.4获取
	public Student getStudent(String studentID) {
		return map.get(studentID);
		}
	
	//3. 计算全班某门课的平均成绩
	public double averageScore(int courseIndex) {
		double sum = 0;
		Set set = map.keySet();
		Iterator it = set.iterator();
		while(it.hasNext()) {
			String key=(String)it.next();
			Student s = map.get(key);
			sum += s.getScore()[courseIndex];
		}
		return sum/map.size();
		
	}
}

- Student.java
package org.ngweb.student.model;
//1. 扩展继承Person类
public class Student extends Person {
	//2. 自己的属性
	//3. 最大的课程门数,课程名称
	public static final int maxCourse = 3;
	public static String[] courseName = {"语文","数学","英语"};
	
	private int[] score;//4. 乘积数组
	//5. 只需要对score设置get、set方法
	
	//7. 创建自己的构造方法:
	public Student() {
		super();
		int[] score = {0,0,0};
		this.score = score;
	}
	
	public Student(String name, int age, String email,int[] score) throws ValidatorException {
		super(name , age, email);
		setScore(score);
	}
	public int[] getScore() {
		return score;
	}

	public void setScore(int[] score)throws ValidatorException{
		//7. 对乘积进行校验
		for(int i = 0;i<maxCourse;i++) {
			if(score[i]<0 || score[i]>100) {
				score[i]=-1;
				this.score = null;
			throw new ValidatorException(courseName[i]+"的成绩超出百分制的范围。");
			}
		}

		this.score = score;
	}
	
	//6. 一个只读性变量,用于返回一个学生成绩的平均值
	public double getAvScore() {
		double sum = 0;
		for (int i= 0;i<maxCourse;i++) {
			sum +=score[i];
		}
		return sum/maxCourse;
	}
	
	
	
}

- ValidatorException.java
package org.ngweb.student.model;
//自定义异常
public class ValidatorException extends Exception{
	public ValidatorException(String msg) {
		super(msg);
	}
}

- DaoTest.java
package org.ngweb.student.test;

import org.ngweb.student.dao.SchoolClassDAO;
import org.ngweb.student.model.*;

import junit.framework.*;

public class DaoTest extends TestCase {
	public void testDao(){
		SchoolClassDAO dao = new SchoolClassDAO("d:/class831");
		SchoolClass shoolClass = new SchoolClass();
		
		Student student;
		try {
			student = new Student("王明", 23, "wangm@qq.com", new int[] {
					82, 93, 88 });
			student.setId("1001");
			shoolClass.insertStudent(student);
			student = new Student("李倩", 22, "liq@qq.com", new int[] {
					94, 89, 91 });
			student.setId("1002");
			shoolClass.insertStudent(student);
			dao.save(shoolClass);
		} catch (ValidatorException e) {
			e.printStackTrace();
		}
		// read from file
		SchoolClass shoolClass1 = new SchoolClass();
		
		Student s;
		shoolClass1=dao.read();
		s = shoolClass1.getStudent("1001");
		Assert.assertEquals("王明", s.getName());
	}
}

- StudentTest.java
package org.ngweb.student.test;

import org.ngweb.student.model.Student;
import org.ngweb.student.model.ValidatorException;

public class StudentTest {


	public static void main(String[] args) {
		Student[] student = new Student[2];

		try {
			student[0] = new Student("王明", 23, "wangm@qq.com", new int[] {
					82, 93, 88 });
		} catch (ValidatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			student[1] = new Student("李倩", 22, "liq@qq.com", new int[] {
					94, 89, 91 });
		} catch (ValidatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		for (int i = 0; i < student.length; i++) {
			System.out.println("\n第" + (i + 1) + "位学生的信息如下 :");
			System.out.println("\t姓名=" + student[i].getName() + ", 年龄="
					+ student[i].getAge() + ", 电子邮件=" + student[i].getEmail());
			System.out.print("\t\t成绩为:");
			for (int j = 0; j < Student.maxCourse; j++) {
				System.out.print(Student.courseName[j] + "="
						+ student[i].getScore()[j] + " ");
			}
			System.out.print("\n\t\t平均成绩为:");
			System.out.println(student[i].getAvScore());
		}


	}

}

- StudentUnitTest.java
package org.ngweb.student.test;

import org.ngweb.student.model.Student;
import org.ngweb.student.model.ValidatorException;

import junit.framework.Assert;
import junit.framework.TestCase;

public class StudentUnitTest extends TestCase {
	public void testValidateName1(){
		Student s = new Student();
		try {
			s.setName("李");
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals("", s.getName());
	}
	public void testValidateName2(){
		Student s = new Student();
		try {
			s.setName("错误的名字");
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals("", s.getName());
	}
	public void testValidateName3(){
		Student s = new Student();
		try {
			s.setName("李明");
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals("李明", s.getName());
	}
	public void testValidateAge1(){
		Student s = new Student();
		try {
			s.setAge(32);
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals(-1, s.getAge());
	}
	public void testValidateAge2(){
		Student s = new Student();
		try {
			s.setAge(12);
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals(-1, s.getAge());
	}
	public void testValidateAge3(){
		Student s = new Student();
		try {
			s.setAge(22);
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals(23, s.getAge());
	}
	public void testValidateEmail1(){
		Student s = new Student();
		try {
			s.setEmail("abc#aa.cc");
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals("", s.getEmail());
	}
	public void testValidateEmail2(){
		Student s = new Student();
		try {
			s.setEmail("abc@aa.cc");
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals("abc@aa.cc", s.getEmail());
	}
	public void testValidateScore(){
		Student s = new Student();
		try {
			s.setScore( new int[] {101, 93, 88 });
		} catch (ValidatorException e) {
			System.out.println(e.getMessage());
		}
		Assert.assertEquals(null, s.getScore());
	}
}

- StudentMgrSys.java
package org.ngweb.student.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

import org.ngweb.student.dao.SchoolClassDAO;
import org.ngweb.student.model.*;

public class StudentMgrSys extends JFrame implements ActionListener {
	// 通过班级来管理班上的学生
	private SchoolClass schoolClass = new SchoolClass();
	
	// 当前显示的学生的索引号
	private int currentStudent=0;
	
	// 班级串行化后保存的文件名
	String fileName = "d:/student";
	
	// 用于显示和输入的输入框, 每个属性一个输入框
	// 由于它们需要在监听器内被访问,所以作为成员变量处理
	JTextField sId = new JTextField(16);  	// ID
	JTextField name = new JTextField(16); 	// 姓名
	JTextField age = new JTextField(16);  	// 年龄
	JTextField email = new JTextField(16);  // 邮件
	JTextField chinese = new JTextField(16);// 语文成绩
	JTextField math = new JTextField(16);	// 数学成绩
	JTextField english = new JTextField(16);// 英语成绩
	
	// 状态显示标签
	JLabel lMsg = new JLabel("记录数:");
	
	public static void main(String[] args) {
		// 主方法, 调用构造方法
		new StudentMgrSys();
	}

	public StudentMgrSys(){
		// 构造方法
		
		// 设置窗口标题和关闭时的动作
		super("学生管理系统");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		// 创建一个JPanel,它将被加入到JFrmae中
		JPanel p = new JPanel();
		// 用简单的流布局
		p.setLayout(new FlowLayout());

		// 字段标记
		JLabel lId = new JLabel("ID:");
		JLabel lName = new JLabel("姓名");
		JLabel lAge = new JLabel("年龄");
		JLabel lEmail = new JLabel("邮件");
		JLabel lChinese = new JLabel("语文");
		JLabel lMath = new JLabel("数学");
		JLabel lEnglish = new JLabel("英语");

		// 所有的按钮,每个按钮都有一个对应的ActionCommand
		// ActionCommand用于在监听器中识别不同的按钮
		JButton saveStudent = new JButton("保存到文件");
		saveStudent.setActionCommand("save");
		JButton readStudent = new JButton("从文件读取");
		readStudent.setActionCommand("read");
		JButton prevStudent = new JButton("上一条记录");
		prevStudent.setActionCommand("prev");
		JButton nextStudent = new JButton("下一条记录");
		nextStudent.setActionCommand("next");
		JButton newStudent = new JButton("添加一个学生");
		newStudent.setActionCommand("new");
		JButton delStudent = new JButton("删除当前学生");
		delStudent.setActionCommand("del");

		// 为上述按钮添加监听器
		// 监听器是this, 因为类本身实现了 ActionListener
		// 并且也覆盖了必须的actionPerformed()方法
		saveStudent.addActionListener(this);
		readStudent.addActionListener(this);
		prevStudent.addActionListener(this);
		nextStudent.addActionListener(this);
		newStudent.addActionListener(this);
		delStudent.addActionListener(this);
		
		// 输入框不可编辑, 在读入文件, 或添加学生后改为可编辑
		setEditable(true);
		sId.setEnabled(false); //学号是自动管理的,不能被修改
		
		// 依次添加标签和文本输入框
		p.add(lId);
		p.add(sId);
		
		p.add(lName);
		p.add(name);

		p.add(lAge);
		p.add(age);

		p.add(lEmail);
		p.add(email);

		p.add(lChinese);
		p.add(chinese);
		p.add(lMath);
		p.add(math);
		p.add(lEnglish);
		p.add(english);

		// 添加按钮
		p.add(saveStudent);
		p.add(readStudent);
		p.add(prevStudent);
		p.add(nextStudent);
		p.add(newStudent);
		p.add(delStudent);

		// 添加状态显示标签
		p.add(lMsg);
		
		// 上述的标签、文本输入框、按钮都是在JPanel上的
		// 将JPanel加入到类本身,因为类是extends JFrame的
		// 所以这个类就是JFrame
		this.add(p);
		
		// 设置大小和显示
		this.setSize(250, 380);
		this.setVisible(true);
		
		// 外观界面编写完成
		// 注:所有按钮的动作在actionPerformed中实现
	}

	// 将当前学生信息取出显示到屏幕上
	private void getStudent(){
		// 取出学生
		Student s = schoolClass.getStudent(currentStudent);
		// 将信息显示到输入文框上
		sId.setText(s.getId());
		name.setText(s.getName());
		age.setText(Integer.toString(s.getAge()));
		email.setText(s.getEmail());
		chinese.setText(Integer.toString(s.getScore()[0]));
		math.setText(Integer.toString(s.getScore()[1]));
		english.setText(Integer.toString(s.getScore()[2]));
	}
	
	// 将用户修改的信息存入schoolClass中
	private boolean putStudent(){
		if(schoolClass.getStudentCount()==0){
			// 如果schoolClass中没有学生,应该加一条记录
			schoolClass.insertStudent(new Student());
			currentStudent=0;
		}
		// 取出当前的学生
		Student s = schoolClass.getStudent(currentStudent);
		try {
			// 将文本输入框的内容更新到学生信息中,
			// 注意:这里异常的处理
			s.setName(name.getText());
			s.setAge(Integer.parseInt(age.getText()));
			s.setEmail(email.getText());
			int[] score = new int[3];
			score[0] = Integer.parseInt(chinese.getText());
			score[1] = Integer.parseInt(math.getText());
			score[2] = Integer.parseInt(english.getText());
			s.setScore(score);
		} catch (ValidatorException e) {
			// ValidatorException是在前面的项目中的自定义异常
			showMsg(e.getMessage());
			return false;
		}
		// 更新,即更新当前的学生信息
		schoolClass.updateStudent(s);
		return true;
	}
	
	void setEditable(boolean editable){
		// 设置文本框为可编辑或不可编辑
		name.setEditable(editable);
		age.setEditable(editable);
		email.setEditable(editable);
		chinese.setEditable(editable);
		math.setEditable(editable);
		english.setEditable(editable);
	}
	
	void showMsg(String msg){
		// 显示一个对话框和提示信息
		JOptionPane.showMessageDialog(this, msg);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// 在监听器中实现按钮的功能
		boolean hasMsg=false;
		if ("new".equals(e.getActionCommand())) {
			if(schoolClass.getStudentCount()>0){
				if(!putStudent()){
					// 没有通过校验,因此,不能继续
					return;
				}
			}
		}else if (!"read".equals(e.getActionCommand())) {
			if(!putStudent()){
				// 没有通过校验,因此,不能继续
				return;
			}
		}
		
		if ("save".equals(e.getActionCommand())) {
			// 保存文件
			SchoolClassDAO dao = new SchoolClassDAO(fileName);
			dao.save(schoolClass);
		}
		
		if ("read".equals(e.getActionCommand())) {
			// 读取文件
			SchoolClassDAO dao = new SchoolClassDAO(fileName);
			schoolClass = dao.read();
			getStudent();
			setEditable(true);
		}
		
		if ("new".equals(e.getActionCommand())) {
			// 新建学生
			Student s = new Student();
			schoolClass.insertStudent(s);
			currentStudent = schoolClass.getStudentCount()-1;
			getStudent();
			setEditable(true);
		}
		if ("prev".equals(e.getActionCommand())) {
			// 上一条记录
			if(currentStudent>0){
				currentStudent--;
				getStudent();
			}else{
				lMsg.setText("已经是第一条记录。");
				hasMsg=true;
			}
		}
		if ("next".equals(e.getActionCommand())) {
			// 下一条记录
			if(currentStudent<schoolClass.getStudentCount()-1){
				currentStudent++;
				getStudent();
			}else{
				lMsg.setText("已经是最后一条记录。");
				hasMsg=true;
			}
		}
		if ("del".equals(e.getActionCommand())) {
			// 删除当前记录
			Student s = new Student();
			s.setId(sId.getText());
			schoolClass.deleteStudent(s);
			if(currentStudent>=schoolClass.getStudentCount()){
				currentStudent--;
			}
			getStudent();
		}
		if(!hasMsg){
			lMsg.setText("记录数:"+(currentStudent+1)+"/"+(schoolClass.getStudentCount()));
		}
	}
}


3、关键问题

正则表达式在此项目中作用,用于检测邮件是否符合规范

image-20210707174139740

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无法长大的Panda

您的鼓励是最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值