0.写在前面

  1. 展示的是很常规的《学生成绩管理系统》,但是可修改为任何管理系统,只需要改些字段即可,具备java基础即可
  2. 简单的增删改查均可实现,本来很简单的几页文档就能交了,老师非得让详细介绍,前前后后做了几个PPT,什么开题报告,结题报告,文档详细,视频录制说明等等面子工程。
  3. 交了两个版本,第一个是javaswing,第二个是一个小型的javaweb
  4. 下面的是javaswing部分,有些截图和介绍显得很多余(纯粹是为了凑作业文档页数)
  5. 成品和打包源码等考完试上传!

1、技术类型

  • java
  • JDBC
  • swing
  • mysql

2、搭建环境

  • windows10
  • maven 3.6.1
  • IDEA 2021.1
  • mysql 5.7.19
  • Sqlyog (也可采用sql server 、Navicat等数据库管理工具,当然在IDEA中也可进行配置mysql驱动进行管理,以上方式均可)

以上只是我的开发环境,不用刻意关注版本问题,基本都可运行。

3、数据库准备

字段

在这里插入图片描述

准备两个数据库表,一个用于登录验证,一个用于学生信息展示

  • 将下列代码在sqlyog中运行即可
-- 创建数据库
CREATE DATABASE `student_gui`;
-- 管理表
CREATE TABLE `manage`(
	`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
	`user_name` VARCHAR(50) NOT NULL DEFAULT 'admin' COMMENT '用户名',
	`pwd` VARCHAR(50) NOT NULL DEFAULT '123456' COMMENT '密码',
	PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;


-- 学生表
CREATE TABLE `student`(
	`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '主键',
	`name` VARCHAR(50) NOT NULL DEFAULT '林小秦' COMMENT '姓名',
	`no` VARCHAR(50) NOT NULL DEFAULT '2019101014' COMMENT '学号',
	`home_town` VARCHAR(50) NOT NULL DEFAULT '菏泽曹县' COMMENT '家庭地址',
	`cn_score` DOUBLE NOT NULL DEFAULT '150' COMMENT '语文成绩',
	`en_score` DOUBLE NOT NULL DEFAULT '150' COMMENT '英语成绩',
	`math_score` DOUBLE NOT NULL DEFAULT '150' COMMENT '数学成绩',
	PRIMARY KEY (`id`)

)ENGINE=INNODB DEFAULT CHARSET=utf8;

登录验证表 manage

在这里插入图片描述

注:这里的 user_name 就是登录用户名

pwd 就是登录密码

大家可以独立设置自己的用户名和密码,之后登录需要用到。

学生信息表 student

在这里插入图片描述

这里我就不放具体数据了,大家自己可以用sql语句插入,或者在sqlyog里面进行插入数据,这里我以自己创建的信息为例!

-v- 这样数据库表就创建完成了,下面进行IDEA操作

4、快速介绍

4.1、登录页面

在这里插入图片描述

设计思路

  1. 检测用户名与密码输入,无论正确与否都会输出至控制台,实时打印日志,友好报错提示

在这里插入图片描述


  1. 检测用户名与密码正确与否,以下情况均不通过
    • 只输入用户名
    • 只输入密码
    • 用户名错误
    • 密码错误
    • 用户名、密码均错误

在这里插入图片描述

在这里插入图片描述

这里没有输出密码,应该是以用户名为准进行输入,如用户名为空则不输出

在这里插入图片描述


  1. 重置,清除用户名和密码输入数据,思路是将这两个输入框的数值设为空

在这里插入图片描述

  1. 登录按钮按键绑定,绑定为人为习惯性的回车键,即点击登录 = 按下 Enter

  2. 登录页面大小锁定,无法进行最大化与页面拉伸,这是因为所有组件按钮输入框以及文本框都有计算好屏幕位置,如可拉伸会影响美观,如图:

在这里插入图片描述

如果想进行页面拉伸,只需将LoginView 类下的

setResizable(false);

参数改为true 即可!(下方有源码展示)


4.2、主页面

输入正确的用户名与密码,即我们创建的数据库manage中的 user_namepwd字段,即可进入主页面

  1. 登录自动销毁登录页面,并动态计算屏幕尺寸,不占用任务栏的情况下全屏铺满主页面,并进行数据排序(根据数据库id主键由大到小)

在这里插入图片描述

为了演示我们不占用任务栏位置特色,我们将任务栏换位置进行再次测试如图

在这里插入图片描述

注意:这里的动态是指每次程序启动时动态计算屏幕尺寸并铺满屏幕,如果在程序启动途中进行任务栏的改变是无效的,这也是后期需要改进的一点!


  1. 主界面可动态拉伸,不会影响表格,表格会随着鼠标拖动响应式展示

在这里插入图片描述

当然你也可以极限拖动,显示如下,默认以点显示!缺点是按钮只能进行隐藏,不能进行按钮的缩放,后期看可否改进。

在这里插入图片描述


  1. 基于上述拖动,设置滚动条,如图

在这里插入图片描述


  1. 分页功能实现,增添上一页,下一页按钮,且进行数据列表检测,当位于第一页时,无法进行上一页翻页,则隐藏上一页按钮,如上图,当无法进行最后一页翻页时,隐藏下一页按钮

在这里插入图片描述

在这里插入图片描述


4.3、增加

  1. 点击增加按钮,进行增加学生信息

在这里插入图片描述

  1. 增添成功,显示消息弹窗,之后在数据库进行查看

在这里插入图片描述

在solyog里面查看,数据添加成功

在这里插入图片描述


4.4、修改

  1. 当不选择行,或者选择多行均提示消息弹出进行修改限制

在这里插入图片描述

在这里插入图片描述

  1. 限制只能修改一行,多行修改需要循环读取编号,这也是可以改进的点
  2. 修改不允许修改编号,设置学生编号不可编辑,因为编号对应数据库主键id,如果修改会造成数据混乱,也不会进行排序功能

在这里插入图片描述

在这里插入图片描述

数据库这边进行查看,编号为83号
在这里插入图片描述

更新成功!

  1. 日志提示,sql语句显示

在这里插入图片描述

4.5、删除

  1. 删除误差提醒,若并没有选择相应数据进行删除,则进行提醒

在这里插入图片描述

  1. 可以进行单行、与多行删除操作,即提供单个与批量删除功能,并进行删除确认操作,防止误删

在这里插入图片描述

在这里插入图片描述

  1. 删除之后,编号重新排序,采用链表删除节点思维,重新进行排序
  2. 这里为了数据库的完整性,就不进行删除演示,可在源码中自己实验即可
  3. 控制台日志打印,打印sql语句,可以后期进行增添删除其余功能

在这里插入图片描述


4.6、查询

  1. 查询由输入框和查询按钮组件组成,只提供了姓名模糊查询功能

在这里插入图片描述

  1. 当查询结果数据不足以显示一页,自动隐藏分页按钮

在这里插入图片描述

  1. 日志提示

在这里插入图片描述

在这里插入图片描述

5、快速开始

  1. 在IDEA中新建一个普通maven项目

  2. 新建以下包

    • entity
    • handler
    • req
    • res
    • service
    • studentview
    • util

如图是我的架构图

在这里插入图片描述

6、导入依赖

pom.xml 里面导入 数据库 mysql 依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
</dependencies>

导入之后刷新 maven

7、utils

在 utils 包下新建类 DBUtils ,封装连接数据库操作

在utils 包下新建类DimensionUtil ,保证主界面不会覆盖电脑屏幕的任务栏

DBUtils

package com.qin.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class DBUtil {
    private static final String URL = "jdbc:mysql://localhost:3306/student_gui?useUnicode=true&characterEncoding=utf-8&useSSL=false";
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String USER_NAME = "root";
    private static final String PWD = "123456";
    static {
        try {
            Class.forName(DRIVER);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获取数据库连接
    public static Connection getConn(){
        try {
            return DriverManager.getConnection(URL,USER_NAME,PWD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void closeConn(Connection connection) {
        if(connection != null){
            try {
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static  void closePs(PreparedStatement ps){
        if(ps != null){
            try {
                ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void closeRs(ResultSet rs){
        if(rs != null){
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

DimensionUtil

package com.qin.util;

import javax.swing.*;
import java.awt.*;

public class DimensionUtil {
    public static Rectangle getBounds() {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        // 保证主界面不会覆盖电脑屏幕的任务栏
        Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(new JFrame().getGraphicsConfiguration());

        Rectangle rectangle = new Rectangle(screenInsets.left, screenInsets.top, screenSize.width - screenInsets.left - screenInsets.right, screenSize.height - screenInsets.top - screenInsets.bottom);

        return rectangle;
    }
}

8、res

在包 res 包下新建类 TableDTO,封装表格是数据

package com.qin.res;

import java.util.Vector;

/**
 * 表格数据传输对象
 */
public class TableDTO {
    private Vector<Vector<Object>> data;
    private int totalCount;

    public Vector<Vector<Object>> getData() {
        return data;
    }

    public void setData(Vector<Vector<Object>> data) {
        this.data = data;
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }
}

9、req

在包req下新建StudentRequest

package com.qin.req;

public class StudentRequest {
    private int pageNow;
    private int pageSize;
    private int start;

    // 查询词
    private String searchKey;


    public int getStart(){
        return (pageNow - 1 )* pageSize;
    }

    public int getPageNow() {
        return pageNow;
    }

    public void setPageNow(int pageNow) {
        this.pageNow = pageNow;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public String getSearchKey() {
        return searchKey;
    }

    public void setSearchKey(String searchKey) {
        this.searchKey = searchKey;
    }
}

10、entity

在包 entity 下新建 登录用户名类AdminDO 和学生信息类 StudentDO

AdminDO

package com.qin.entity;

public class AdminDO {
    private Integer id;
    private String userName;
    private String pwd;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

StudentDO

package com.qin.entity;

public class StudentDO {
    private  Integer id;
    private  String name;
    private  String no;
    private  String homeTown;
    private Double cnScore;
    private Double mathScore;
    private Double enScore;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

    public String getHomeTown() {
        return homeTown;
    }

    public void setHomeTown(String homeTown) {
        this.homeTown = homeTown;
    }

    public Double getCnScore() {
        return cnScore;
    }

    public void setCnScore(Double cnScore) {
        this.cnScore = cnScore;
    }

    public Double getMathScore() {
        return mathScore;
    }

    public void setMathScore(Double mathScore) {
        this.mathScore = mathScore;
    }

    public Double getEnScore() {
        return enScore;
    }

    public void setEnScore(Double enScore) {
        this.enScore = enScore;
    }
}

这里也可以用Lombok插件,导入Lombok依赖,然后在类上增加注解@Date ,作用是自动生成 getter 和 setter 方法

11、service

在包 service 下新建接口 AdminService 和 接口 StudentService ,继而创建实现类 AdminServiceImpl 和实现类 StudentServiceImpl

AdminService 接口

package com.qin.service;

import com.qin.entity.AdminDO;

public interface AdminService {
    boolean validateAdmin(AdminDO adminDO);
}

StudentService 接口

package com.qin.service;

import com.qin.entity.StudentDO;
import com.qin.req.StudentRequest;
import com.qin.res.TableDTO;

public interface StudentService {

    TableDTO retrieveStudents(StudentRequest request);

    boolean add(StudentDO studentDO);

    StudentDO getById(int selectedStudentId);

    boolean update(StudentDO studentDO);

    boolean delete(int[] selectedStudentIds);
}

AdminServiceImpl 实现类

package com.qin.service;

import com.qin.entity.AdminDO;
import com.qin.util.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class AdminServiceImpl implements AdminService{
    @Override
    public boolean validateAdmin(AdminDO adminDO) {
        String userName = adminDO.getUserName();
        String pwdParam = adminDO.getPwd();
        if(userName == null || "".equals(userName.trim())){
            return false;
        }


        String sql = "select pwd from manage where user_name = ?";

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        try {
            conn = DBUtil.getConn();
            if(conn == null){
                return false;
            }
            ps = conn.prepareCall(sql);
            ps.setString(1, adminDO.getUserName());
            resultSet = ps.executeQuery();
            while(resultSet.next()){
                String pwd= resultSet.getString(1);
                if(adminDO.getPwd().equals(pwd)){
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBUtil.closeRs(resultSet);
            DBUtil.closePs(ps);
            DBUtil.closeConn(conn);

        }
        return false;
    }
}

StudentServiceImpl

package com.qin.service;

import com.qin.entity.StudentDO;
import com.qin.req.StudentRequest;
import com.qin.res.TableDTO;
import com.qin.util.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

public class StudentServiceImpl implements StudentService{
    @Override
    public TableDTO retrieveStudents(StudentRequest request) {
        StringBuilder sql = new StringBuilder();
        sql.append("select * from `student` ");
        if(request.getSearchKey() != null && !"".equals(request.getSearchKey().trim())){
            sql.append("where name like '%"+request.getSearchKey().trim()+"%'");
        }
        sql.append("order by id desc limit ").append(request.getStart()).append(",")
                .append(request.getPageSize());
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        TableDTO returnDTO = new TableDTO();
        try{
            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql.toString());
            rs = ps.executeQuery();
            // 查询记录
            returnDTO.setData(fillData(rs));
            sql.setLength(0);
            sql.append("select count(*) from student ");
            if(request.getSearchKey() != null && ! "".equals(request.getSearchKey().trim())){
                sql.append("where name like '%"+request.getSearchKey().trim()+"%'");
                System.out.println("sql语句为[" + sql + "]");
                System.out.println("您查询了名字中含有" + request.getSearchKey().trim() + "的同学!");
            }
            ps = conn.prepareStatement(sql.toString());
            rs = ps.executeQuery();

            while(rs.next()){
                int count = rs.getInt(1);
                returnDTO.setTotalCount(count);
            }
            return returnDTO;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DBUtil.closeRs(rs);
            DBUtil.closePs(ps);
            DBUtil.closeConn(conn);
        }
        return null;
    }

    @Override
    public boolean add(StudentDO studentDO) {
        StringBuilder sql = new StringBuilder();
        sql.append(" insert into student(name,no,home_town,cn_score,en_score,math_score)");
        sql.append(" values(?,?,?,?,?,?)");
        Connection conn = null;
        PreparedStatement ps = null;
        try{
            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql.toString());
            ps.setString(1, studentDO.getName());
            ps.setString(2, studentDO.getNo());
            ps.setString(3, studentDO.getHomeTown());
            ps.setDouble(4, studentDO.getCnScore());
            ps.setDouble(5, studentDO.getMathScore());
            ps.setDouble(6, studentDO.getEnScore());
            return ps.executeUpdate() == 1;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DBUtil.closePs(ps);
            DBUtil.closeConn(conn);
        }
        return false;
    }

    @Override
    public StudentDO getById(int selectedStudentId) {
        StringBuilder sql = new StringBuilder("select * from student where id = ? ");

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        StudentDO studentDO = new StudentDO();
        try{
            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql.toString());
            ps.setInt(1,selectedStudentId);
            rs = ps.executeQuery();
            while(rs.next()){
                // 处理查出的每一条记录
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String no = rs.getString("no");
                String homeTown = rs.getString("home_town");
                double cnScore = rs.getDouble("cn_score");
                double enScore = rs.getDouble("en_score");
                double mathScore = rs.getDouble("math_score");
                studentDO.setId(id);
                studentDO.setName(name);
                studentDO.setNo(no);
                studentDO.setHomeTown(homeTown);
                studentDO.setCnScore(cnScore);
                studentDO.setEnScore(enScore);
                studentDO.setMathScore(mathScore);
            }
            return studentDO;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DBUtil.closeRs(rs);
            DBUtil.closePs(ps);
            DBUtil.closeConn(conn);
        }
        return null;
    }

    @Override
    public boolean update(StudentDO studentDO) {
        StringBuilder sql = new StringBuilder();
        sql.append("update `student` set `name`=?,`no`=?,`home_town`=?,`cn_score`=?,`en_score`=?,`math_score`=?");
        sql.append("where id =?");
        System.out.println("修改sql语句: [" + sql + "]");
        Connection conn = null;
        PreparedStatement ps = null;
        try{

            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql.toString());
            ps.setString(1, studentDO.getName());
            ps.setString(2, studentDO.getNo());
            ps.setString(3, studentDO.getHomeTown());
            ps.setDouble(4, studentDO.getCnScore());
            ps.setDouble(5, studentDO.getEnScore());
            ps.setDouble(6, studentDO.getMathScore());
            ps.setInt(7, studentDO.getId());
            return ps.executeUpdate() == 1;

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DBUtil.closePs(ps);
            DBUtil.closeConn(conn);
        }
        return false;
    }

    @Override
    public boolean delete(int[] selectedStudentIds) {
        StringBuilder sql = new StringBuilder();
        sql.append("delete from `student` where id in( ");
        int length = selectedStudentIds.length;
        for(int i = 0;i <length;i++){
            if(i == (length-1)){
                sql.append(" ? ");
            }else{
                sql.append(" ?, ");
            }
        }
        sql.append(")");
        System.out.println("删除的sql语句为:[" + sql + "]");

        Connection conn = null;
        PreparedStatement ps = null;
        try{
            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql.toString());
            for(int i = 0;i <length;i++){
                // 设置参数,从1开始
                ps.setInt(i+1,selectedStudentIds[i]);
            }
            return ps.executeUpdate() == length;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            DBUtil.closePs(ps);
            DBUtil.closeConn(conn);
        }
        return false;
    }

    private Vector<Vector<Object>> fillData(ResultSet rs) throws SQLException {
        Vector<Vector<Object>> data = new Vector<>();
        while(rs.next()){
            // 处理查出的每一条记录
            Vector<Object> oneRecord = new Vector<>();
            int id = rs.getInt("id");
            String name = rs.getString("name");
            String no = rs.getString("no");
            String homeTown = rs.getString("home_town");
            double cnScore = rs.getDouble("cn_score");
            double enScore = rs.getDouble("en_score");
            double mathScore = rs.getDouble("math_score");
            double totalScore = cnScore + enScore + mathScore;
            oneRecord.add(id);
            oneRecord.add(name);
            oneRecord.add(no);
            oneRecord.add(homeTown);
            oneRecord.add(cnScore);
            oneRecord.add(enScore);
            oneRecord.add(mathScore);
            oneRecord.add(totalScore);
            data.addElement(oneRecord);
        }
        return data;
    }
}

12、handler

  1. 在包 handler 下新建 AddStudentViewHandler 类,作用是对添加按钮进行事件处理
package com.qin.handler;

import com.qin.entity.StudentDO;
import com.qin.service.StudentService;
import com.qin.service.StudentServiceImpl;
import com.qin.studentview.AddStudentView;
import com.qin.studentview.MainView;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AddStudentViewHandler implements ActionListener {
    private AddStudentView addStudentView;
    private MainView mainView;
    public AddStudentViewHandler(AddStudentView addStudentView, MainView mainView){
        this.addStudentView = addStudentView;
        this.mainView = mainView;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton jButton = (JButton) e.getSource();
        String text = jButton.getText();
        if("添加".equals(text)){
            StudentService studentService = new StudentServiceImpl();
            StudentDO studentDO = addStudentView.buildStudentDO();
            boolean addResult = studentService.add(studentDO);
            if(addResult){
                //重新加载表格查到最终数据
                mainView.reloadTable();
                addStudentView.dispose();
                JOptionPane.showMessageDialog(addStudentView,"添加成功");
            }else{
                JOptionPane.showMessageDialog(addStudentView,"添加失败");
            }
        }
    }
}
  1. 在包 handler 下新建 LoginHandler 类,作用是对登录按钮和重置进行事件处理,并且增加按键绑定时间,在登录页面输入账号密码按回车键即可执行登录按钮操作
package com.qin.handler;

import com.qin.entity.AdminDO;
import com.qin.service.AdminServiceImpl;
import com.qin.studentview.LoginView;
import com.qin.studentview.MainView;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/**
 * handler: 处理事件
 */
public class LoginHandler extends KeyAdapter implements ActionListener {
    private LoginView loginView;
    public LoginHandler(LoginView loginView){
        this.loginView = loginView;
    }
    // 回车按键绑定
    @Override
    public void keyPressed(KeyEvent e) {
        if (KeyEvent.VK_ENTER == e.getKeyCode()){
            login();
        }

    }
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton jButton = (JButton) e.getSource();
        String text = jButton.getText();
        if("重置".equals(text)){
            loginView.getUserTxt().setText("");
            loginView.getPwdField().setText("");
        }else if("登录".equals(text)){
            login();
        }

    }
    private void login(){
        String user = loginView.getUserTxt().getText();
        char[] chars = loginView.getPwdField().getPassword();
        if(user == null || "".equals(user.trim()) || chars == null){
            JOptionPane.showMessageDialog(loginView,"用户名密码必填!");
            return;
        }
        String pwd = new String(chars);
        System.out.println(user + ":" + pwd);

        // 查询db
        AdminServiceImpl adminService = new AdminServiceImpl();
        AdminDO adminDO = new AdminDO();
        adminDO.setUserName(user);
        adminDO.setPwd(pwd);
        boolean flag = adminService.validateAdmin(adminDO);
        if(flag) {
            // 跳转到主界面并销毁登录界面
            new MainView();
//            JOptionPane.showMessageDialog(loginView,"登录成功");
            loginView.dispose();
        }else {
            JOptionPane.showMessageDialog(loginView,"用户名密码错误");
        }

    }
}
  1. 在包 handler 下新建 MainViewHandler 类,作用是对主页面的增加、删除、查找按钮进行事务绑定
package com.qin.handler;

import com.qin.service.StudentService;
import com.qin.service.StudentServiceImpl;
import com.qin.studentview.AddStudentView;
import com.qin.studentview.MainView;
import com.qin.studentview.UpdateStudentView;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * handler: 处理事件的
 */
public class MainViewHandler implements ActionListener {
    private MainView mainView;
    public MainViewHandler(MainView mainView){
        this.mainView = mainView;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton jButton = (JButton) e.getSource();
        String text = jButton.getText();
        if("增加".equals(text)){
            new AddStudentView(mainView);
        }else if("修改".equals(text)){
            int[] selectedStudentIds = mainView.getSelectedStudentIds();
            if(selectedStudentIds.length !=1){
                JOptionPane.showMessageDialog(mainView,"一次只能修改一行!");
                return;
            }
            new UpdateStudentView(mainView,selectedStudentIds[0]);
        }else if("删除".equals(text)){
            int[] selectedStudentIds = mainView.getSelectedStudentIds();
            if(selectedStudentIds.length == 0){
                JOptionPane.showMessageDialog(mainView,"请选择删除的行");
                return;
            }
            int option = JOptionPane.showConfirmDialog(mainView, "你确认要删除选择的" +
                    selectedStudentIds.length + "行吗?", "确认删除", JOptionPane.YES_NO_OPTION);
            if(option == JOptionPane.YES_OPTION){
                // 确认执行删除
                StudentService studentService = new StudentServiceImpl();
                boolean deleteResult = studentService.delete(selectedStudentIds);
                if(deleteResult){
                    JOptionPane.showMessageDialog(mainView,"删除成功");
                    //重新加载表格查到最终数据
                    mainView.reloadTable();
                }else{
                    JOptionPane.showMessageDialog(mainView,"删除失败");
                }
            }
        }else if("查询".equals(text)){
            mainView.setPageNow(1);
            mainView.reloadTable();
        }else if("上一页".equals(text)){
            mainView.setPageNow(mainView.getPageNow() - 1);
            mainView.reloadTable();
        }else if("下一页".equals(text)){
            mainView.setPageNow(mainView.getPageNow() + 1);
            mainView.reloadTable();
        }
    }
}
  1. 在包 handler 下新建 UpdateStudentViewHandler 类,作用是对主页面的修改按钮进行事务绑定
package com.qin.handler;

import com.qin.entity.StudentDO;
import com.qin.service.StudentService;
import com.qin.service.StudentServiceImpl;
import com.qin.studentview.MainView;
import com.qin.studentview.UpdateStudentView;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class UpdateStudentViewHandler implements ActionListener {
    private UpdateStudentView updateStudentView;
    private MainView mainView;
    public UpdateStudentViewHandler(UpdateStudentView updateStudentView, MainView mainView){
        this.updateStudentView = updateStudentView;
        this.mainView = mainView;
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton jButton = (JButton) e.getSource();
        String text = jButton.getText();
        if("修改".equals(text)){
            StudentService studentService = new StudentServiceImpl();
            StudentDO studentDO = updateStudentView.buildUpdateStudentDO();
            boolean updateResult = studentService.update(studentDO);
            if(updateResult){
                //重新加载表格查到最终数据
                mainView.reloadTable();
                JOptionPane.showMessageDialog(updateStudentView,"修改成功");
                // 摧毁表单
                updateStudentView.dispose();
            }else{
                JOptionPane.showMessageDialog(updateStudentView,"修改失败");
            }
        }
    }
}

13、studentview

  1. 在包 studentview 下新建MainViewTable类,增加增加、删除、修改、查询按钮,上一页,下一页按钮,设置放置位置与监听事件,以及检测当数据表不足以显示下一页时,隐藏下一页按钮,当数据表不能显示上一页时,隐藏上一页按钮。
package com.qin.studentview;
import com.qin.handler.MainViewHandler;
import com.qin.req.StudentRequest;
import com.qin.res.TableDTO;
import com.qin.service.StudentService;
import com.qin.service.StudentServiceImpl;
import com.qin.util.DimensionUtil;


import javax.swing.*;
import java.awt.*;

public class MainView extends JFrame {
    JPanel northPanel = new JPanel();
    JButton addBtn = new JButton("增加");
    JButton updateBtn = new JButton("修改");
    JButton delBtn = new JButton("删除");
    JTextField searchTxt = new JTextField(15);
    JButton searchBtn = new JButton("查询");
    JPanel southPanel = new JPanel();
    JButton preBtn = new JButton("上一页");
    JButton nextBtn = new JButton("下一页");


    MainViewTable mainViewTable = new MainViewTable();
    private int pageNow = 1; //当前是第几页
    private int pageSize = 10; //一页显示多少条记录
    MainViewHandler mainViewHandler;

    public MainView() {
        super("主界面-学生成绩管理系统V1.0");
        // 获取内容面板
        Container contentPane = getContentPane();
        Rectangle bounds = DimensionUtil.getBounds();
        pageSize = Math.floorDiv(bounds.height,40);
        mainViewHandler = new MainViewHandler(this);

        // 放置北边的组件
        LayoutNorth(contentPane);
        // 设置中间的jtable
        LayoutCenter(contentPane);
        // 放置南边的组件
        LayoutSouth(contentPane);
        // 根据屏幕大小设置主界面大小


        setBounds(bounds);
        // 设置窗体完全充满整个屏幕的可见大小
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(true);
        setVisible(true);


    }

    private void LayoutCenter(Container contentPane) {
        TableDTO dto = getTableDTO();

        MainViewTableModel mainViewTableModel = MainViewTableModel.assembleModel(dto.getData());
        // 把jtable和model关联
        mainViewTable.setModel(mainViewTableModel);
        mainViewTable.renderRule();
        JScrollPane jScrollPane = new JScrollPane(mainViewTable);
        contentPane.add(jScrollPane, BorderLayout.CENTER);
        showPreNext(dto.getTotalCount());
    }

    private TableDTO getTableDTO() {
        StudentService studentService = new StudentServiceImpl();
        StudentRequest request = new StudentRequest();
        request.setPageNow(pageNow);
        request.setPageSize(pageSize);
        request.setSearchKey(searchTxt.getText().trim());
        TableDTO tableDTO = studentService.retrieveStudents(request);
        return tableDTO;
    }


    private void LayoutSouth(Container contentPane) {
        preBtn.addActionListener(mainViewHandler);
        nextBtn.addActionListener(mainViewHandler);
        southPanel.add(preBtn);
        southPanel.add(nextBtn);
        contentPane.add(southPanel, BorderLayout.SOUTH);
    }

    /**
     * 设置上一页和下一页是否可见
     *
     * @param totalCount
     */
    private void showPreNext(int totalCount) {
        if (pageNow == 1) {
            preBtn.setVisible(false);
        } else {
            preBtn.setVisible(true);
        }
        int pageCount = 0; //总共有多少页
        if (totalCount % pageSize == 0) {
            pageCount = totalCount / pageSize;
        } else {
            pageCount = totalCount / pageSize + 1;
        }
        if (pageNow == pageCount) {
            nextBtn.setVisible(false);
        } else {
            nextBtn.setVisible(true);
        }


    }

    private void LayoutNorth(Container contentPane) {
        // 增加事件监听
        addBtn.addActionListener(mainViewHandler);
        updateBtn.addActionListener(mainViewHandler);
        delBtn.addActionListener(mainViewHandler);
        searchBtn.addActionListener(mainViewHandler);
        northPanel.add(addBtn);
        northPanel.add(updateBtn);
        northPanel.add(delBtn);
        northPanel.add(searchTxt);
        northPanel.add(searchBtn);
        contentPane.add(northPanel, BorderLayout.NORTH);
    }


    public static void main(String[] args) {
        new MainView();
    }

    public void setPageNow(int pageNow) {
        this.pageNow = pageNow;
    }

    public int getPageNow() {
        return pageNow;
    }

    public void reloadTable() {
        TableDTO dto = getTableDTO();
        MainViewTableModel.updateModel(dto.getData());
        mainViewTable.renderRule();
        showPreNext(dto.getTotalCount());

    }
    public int[] getSelectedStudentIds(){
        int[] selectedRows = mainViewTable.getSelectedRows();
        int [] ids = new int[selectedRows.length];
        for(int i = 0; i< selectedRows.length;i++){
            int rowIndex = selectedRows[i];
            Object idObj = mainViewTable.getValueAt(rowIndex,0);
            ids[i] = Integer.valueOf(idObj.toString());
        }
        return ids;
    }
}
  1. 在包 studentview 下新建MainViewCellRender类,用来对主页面表格设置隔行变色以及居中显示
package com.qin.studentview;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;

public class MainViewCellRender extends DefaultTableCellRenderer {
    @Override
    // 在每一行的每一列显示之前都会调用
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if(row % 2 == 0){
            setBackground(Color.LIGHT_GRAY);
        }else {
            setBackground(Color.WHITE);
        }
        // 设置水平居中
        setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
        return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    }
}
  1. 在包 studentview 下新建MainViewTable类,用来对主页面表格设置表格体和间距以及对表格的多行选择
package com.qin.studentview;

import javax.swing.*;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.util.Vector;

public class MainViewTable extends JTable {
    public MainViewTable(){
        JTableHeader tableHeader = getTableHeader();
        tableHeader.setFont(new Font(null,Font.BOLD,16));
        tableHeader.setForeground(Color.RED);
        // 设置表格体
        setFont(new Font(null,Font.BOLD,14));
        setForeground(Color.black);
        setGridColor(Color.BLACK);
        setRowHeight(30);
        // 设置多行选择
        getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    }
    public void setDataModel(MainViewTableModel mainViewTableModel){
        this.setModel(mainViewTableModel);
    }

    public void renderRule() {
        // 设置表格列的渲染方式
        Vector<String> columns = MainViewTableModel.getColumns();
        MainViewCellRender render = new MainViewCellRender();
        for(int i = 0; i < columns.size();i++){
            TableColumn column = getColumn(columns.get(i));
            column.setCellRenderer(render);
            if( i == 0){
                // 第一列变窄
                column.setPreferredWidth(50);
//                column.setMaxWidth(50);
                column.setResizable(false);
            }
        }
    }
}
  1. 在包 studentview 下新建MainViewTableModel类,用来对表格表头进行设置
package com.qin.studentview;

import javax.swing.table.DefaultTableModel;
import java.util.Vector;

public class MainViewTableModel extends DefaultTableModel {
// 自定义tablemodel


    static Vector<String> columns = new Vector<>();
    static {
        columns.addElement("编号");
        columns.addElement("姓名");
        columns.addElement("学号");
        columns.addElement("家乡");
        columns.addElement("语文");
        columns.addElement("数学");
        columns.addElement("英语");
        columns.addElement("总分");
    }
    private MainViewTableModel() {
        super(null,columns);
    }
    // 饿汉单例设计模式
    private static MainViewTableModel mainViewTableModel = new MainViewTableModel();

    public static MainViewTableModel assembleModel(Vector<Vector<Object>> data) {
        mainViewTableModel.setDataVector(data,columns);
        return mainViewTableModel;
    }

    public static void  updateModel(Vector<Vector<Object>> data) {
        mainViewTableModel.setDataVector(data,columns);
    }



    public static Vector<String> getColumns() {
        return columns;
    }

    @Override
    public boolean isCellEditable(int row,int column){
        return false;
    }
}
  1. 在包 studentview 下新建AddStudentView类,用来对添加按钮进行事件处理
package com.qin.studentview;

import com.qin.entity.StudentDO;
import com.qin.handler.AddStudentViewHandler;

import javax.swing.*;
import java.awt.*;

public class AddStudentView extends JDialog {
    JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,20));
    JLabel nameLabel = new JLabel("姓名",JLabel.RIGHT);
    JTextField nameTxt = new JTextField();
    JLabel noLabel = new JLabel("学号",JLabel.RIGHT);
    JTextField noTxt = new JTextField();
    JLabel homeLabel = new JLabel("家乡",JLabel.RIGHT);
    JTextField homeTxt = new JTextField();
    JLabel cnLabel = new JLabel("语文成绩",JLabel.RIGHT);
    JTextField cnTxt = new JTextField();
    JLabel mathLabel = new JLabel("数学成绩",JLabel.RIGHT);
    JTextField mathTxt = new JTextField();
    JLabel enLabel = new JLabel("英语成绩",JLabel.RIGHT);
    JTextField enTxt = new JTextField();
    JButton addBtn = new JButton("添加");

    AddStudentViewHandler addStudentViewHandler;





    public AddStudentView(MainView mainView){
        super(mainView,"添加学生",true);
        addStudentViewHandler = new AddStudentViewHandler(this,mainView);


        nameLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(nameLabel);
        nameTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(nameTxt);

        noLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(noLabel);
        noTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(noTxt);

        homeLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(homeLabel);
        homeTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(homeTxt);

        cnLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(cnLabel);
        cnTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(cnTxt);

        mathLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(mathLabel);
        mathTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(mathTxt);

        enLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(enLabel);
        enTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(enTxt);



        addBtn.addActionListener(addStudentViewHandler);
        jPanel.add(addBtn);
        Container contentPane = getContentPane();
        contentPane.add(jPanel);




        setSize(350,500);
        setLocationRelativeTo(null);
        //DISPOSE_ON_CLOSE 只销毁当前的窗体
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
        setVisible(true);

    }


    public StudentDO buildStudentDO(){
        StudentDO studentDO = new StudentDO();
        studentDO.setName(nameTxt.getText());
        studentDO.setNo(noTxt.getText());
        studentDO.setHomeTown(homeTxt.getText());
        studentDO.setCnScore(Double.valueOf(cnTxt.getText()));
        studentDO.setEnScore(Double.valueOf(enTxt.getText()));
        studentDO.setMathScore(Double.valueOf(mathTxt.getText()));
        return studentDO;
    }
}
  1. 在包 studentview 下新建AddStudentView类,用来对添加按钮进行事件处理
package com.qin.studentview;

import com.qin.entity.StudentDO;
import com.qin.handler.AddStudentViewHandler;

import javax.swing.*;
import java.awt.*;

public class AddStudentView extends JDialog {
    JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,20));
    JLabel nameLabel = new JLabel("姓名",JLabel.RIGHT);
    JTextField nameTxt = new JTextField();
    JLabel noLabel = new JLabel("学号",JLabel.RIGHT);
    JTextField noTxt = new JTextField();
    JLabel homeLabel = new JLabel("家乡",JLabel.RIGHT);
    JTextField homeTxt = new JTextField();
    JLabel cnLabel = new JLabel("语文成绩",JLabel.RIGHT);
    JTextField cnTxt = new JTextField();
    JLabel mathLabel = new JLabel("数学成绩",JLabel.RIGHT);
    JTextField mathTxt = new JTextField();
    JLabel enLabel = new JLabel("英语成绩",JLabel.RIGHT);
    JTextField enTxt = new JTextField();
    JButton addBtn = new JButton("添加");

    AddStudentViewHandler addStudentViewHandler;





    public AddStudentView(MainView mainView){
        super(mainView,"添加学生",true);
        addStudentViewHandler = new AddStudentViewHandler(this,mainView);


        nameLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(nameLabel);
        nameTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(nameTxt);

        noLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(noLabel);
        noTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(noTxt);

        homeLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(homeLabel);
        homeTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(homeTxt);

        cnLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(cnLabel);
        cnTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(cnTxt);

        mathLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(mathLabel);
        mathTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(mathTxt);

        enLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(enLabel);
        enTxt.setPreferredSize(new Dimension(200,30));
        jPanel.add(enTxt);



        addBtn.addActionListener(addStudentViewHandler);
        jPanel.add(addBtn);
        Container contentPane = getContentPane();
        contentPane.add(jPanel);




        setSize(350,500);
        setLocationRelativeTo(null);
        //DISPOSE_ON_CLOSE 只销毁当前的窗体
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
        setVisible(true);

    }


    public StudentDO buildStudentDO(){
        StudentDO studentDO = new StudentDO();
        studentDO.setName(nameTxt.getText());
        studentDO.setNo(noTxt.getText());
        studentDO.setHomeTown(homeTxt.getText());
        studentDO.setCnScore(Double.valueOf(cnTxt.getText()));
        studentDO.setEnScore(Double.valueOf(enTxt.getText()));
        studentDO.setMathScore(Double.valueOf(mathTxt.getText()));
        return studentDO;
    }
}
  1. 在包 studentview 下新建LoginView类,用来对登录界面进行组件布置
package com.qin.studentview;

import com.qin.handler.LoginHandler;

import javax.swing.*;
import java.awt.*;

public class LoginView extends JFrame {

    JLabel nameLabel = new JLabel("学生成绩管理系统V1.0",JLabel.CENTER);

    SpringLayout springLayout = new SpringLayout();
    JPanel centerPanel = new JPanel(springLayout);
    JLabel userNameLabel = new JLabel("用户名:");
    JTextField userTxt = new JTextField();
    JLabel pwdLabel = new JLabel("密码:");
    JPasswordField pwdField = new JPasswordField();
    JButton loginBtn = new JButton("登录");
    JButton resetBtn = new JButton("重置");



    LoginHandler loginHandler;
    public LoginView(){
        super("学生成绩管理系统V1.0");
        loginHandler = new LoginHandler(this);


        // 获取内容面板
        Container contentPane = getContentPane();

        nameLabel.setFont(new Font("华文行楷",Font.PLAIN,40));
        nameLabel.setPreferredSize(new Dimension(0,80));

        Font centerFont = new Font("华文行楷", Font.PLAIN, 20);
        userNameLabel.setFont(centerFont);
        userTxt.setPreferredSize(new Dimension(200,30));
        pwdLabel.setFont(centerFont);
        pwdField.setPreferredSize(new Dimension(200,30));
        loginBtn.setFont(centerFont);
        resetBtn.setFont(centerFont);


        // 把组件加入面板
        centerPanel.add(userNameLabel);
        centerPanel.add(userTxt);
        centerPanel.add(pwdLabel);
        centerPanel.add(pwdField);
        loginBtn.addActionListener(loginHandler);

        centerPanel.add(loginBtn);
        resetBtn.addActionListener(loginHandler);
        // 增加按键事件
        loginBtn.addKeyListener(loginHandler);
        centerPanel.add(resetBtn);
        // 设置默认按钮loginBtn,使得此按钮可以相应enter
        getRootPane().setDefaultButton(loginBtn);
        //弹簧布局
        LayoutCenter();
        //设置窗体图标
        Image image = new ImageIcon().getImage();


        contentPane.add(nameLabel,BorderLayout.NORTH);
        contentPane.add(centerPanel,BorderLayout.CENTER);
        setSize(600,400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        setVisible(true);
    }

private void LayoutCenter(){
    //弹簧布局
    // 布局 userNameLabel
    Spring childWidth = Spring.sum(Spring.sum(Spring.width(userNameLabel), Spring.width(userTxt)), Spring.constant(20));
    int offsetX = childWidth.getValue() / 2;
    springLayout.putConstraint(SpringLayout.WEST,userNameLabel,-offsetX,SpringLayout.HORIZONTAL_CENTER,centerPanel);
    springLayout.putConstraint(SpringLayout.NORTH,userNameLabel,20,SpringLayout.NORTH,centerPanel);
    // 布局userTxt
    springLayout.putConstraint(SpringLayout.WEST,userTxt,20,SpringLayout.EAST,userNameLabel);
    springLayout.putConstraint(SpringLayout.NORTH,userTxt,0,SpringLayout.NORTH,userNameLabel);
    // 布局 pwdLabel
    springLayout.putConstraint(SpringLayout.EAST,pwdLabel,0,SpringLayout.EAST,userNameLabel);
    springLayout.putConstraint(SpringLayout.NORTH,pwdLabel,20,SpringLayout.SOUTH,userNameLabel);
    // 布局 pwdField
    springLayout.putConstraint(SpringLayout.WEST,pwdField,20,SpringLayout.EAST,pwdLabel);
    springLayout.putConstraint(SpringLayout.NORTH,pwdField,0,SpringLayout.NORTH,pwdLabel);
    // 布局loginBtn
    springLayout.putConstraint(SpringLayout.WEST,loginBtn,50,SpringLayout.WEST,pwdLabel);
    springLayout.putConstraint(SpringLayout.NORTH,loginBtn,20,SpringLayout.SOUTH,pwdLabel);
    // 布局resetBtn
    springLayout.putConstraint(SpringLayout.WEST,resetBtn,50,SpringLayout.EAST,loginBtn);
    springLayout.putConstraint(SpringLayout.NORTH,resetBtn,0,SpringLayout.NORTH,loginBtn);
}

    public JTextField getUserTxt() {
        return userTxt;
    }

    public JPasswordField getPwdField() {
        return pwdField;
    }


    public static void main(String[] args) {
        new LoginView();
    }


}

14、APP

在第二级包下新建APP类,用来作为整个启动的起点

在这里插入图片描述

package com;

import com.qin.studentview.LoginView;

public class APP {
    public static void main(String[] args) {
        new LoginView();
    }
}

至此,直接启动APP类即可,以上即为所有展示

15、改进与优化

改进部分

  1. 本系统只设立了管理端显示,应该再设立两个学生和教师端,即增加两个用户验证表,增加两个主页面

  2. 在动态计算屏幕尺寸并铺满屏幕时,如果在程序启动后再进行任务栏的改变是无效的,这也是需要改进的一点!

  3. 在主界面动态拖动,表格可响应式发生变动,但是按钮只能显示或隐藏,无法做到和表格一般响应变大与缩小

  4. 在查询中只提供了模糊姓名查询以及精准查询,未提供学号、地址或分数查询

  5. 图表功能可结合JFreeChart - 多功能Java图表类库、ECharts-Java - Java版ECharts图表库进行散点、扇形、比例、柱状等多图表绘制,采用web端展示更方便,在swing中会更复杂。

优化部分

  1. 自定义软件图标,增加软件美观感

在这里插入图片描述

在这里插入图片描述

// 自定义图标
URL imgUrl = LoginView.class.getClassLoader().getResource("qbt.png");
setIconImage(new ImageIcon(imgUrl).getImage());

可在resource目录下拷贝自己所定义的图片,之后在上述代码中修改文件名即可,上述代码可放置LoginView 中,伴随起始项加载

为了演示,之后会在主界面进行图标更换

  1. 增加托盘事件与最小化销毁资源事件,如同大多数桌面端软件一般,最小化显示图标(也叫做托盘)于任务栏,但是不销毁软件,只销毁缓存资源

在这里插入图片描述

if(SystemTray.isSupported()){
            SystemTray systemTray = SystemTray.getSystemTray();
            // 系统托盘图标不宜过大
            URL imgUrl = LoginView.class.getClassLoader().getResource("qbt.png");
            // 设置大小
            TrayIcon trayIcon = new TrayIcon(new ImageIcon(imgUrl).getImage());
            trayIcon.setImageAutoSize(true);
            try {
                systemTray.add(trayIcon);
            } catch (AWTException e) {
                e.printStackTrace();
            }
            // 增加最小化时,销毁资源
            this.addWindowListener(new WindowAdapter() {
                @Override
                public void windowIconified(WindowEvent e) {
                    LoginView.this.dispose();
                }
            });
            // 托盘事件
            trayIcon.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    // 获取鼠标点击次数
                    int clickCount = e.getClickCount();
                    if(clickCount == 1){
                        LoginView.this.setExtendedState(JFrame.NORMAL);
                    }
                    LoginView.this.setVisible(true);
                }
            });
        }

在这里插入图片描述

  1. 为了便于其他人使用此程序,我们将javaswing打包成jar包,这意味着只需要你的电脑上有jre环境,即可运行此程序,对于更便捷性的exe类型文件,由于jar->exe较为复杂,这里就不进行转化了

在这里插入图片描述

解压jar包,您可以看到我们的起始程序类,jar包依赖,以及版本信息和所需的资源信息,在解压后的META-INF -> MANIFEST 文件打开进行查看,我们演示用 notepad++ 打开

在这里插入图片描述

补充UpdateStudentView类

package com.qin.studentview;

import com.qin.entity.StudentDO;
import com.qin.handler.UpdateStudentViewHandler;
import com.qin.service.StudentService;
import com.qin.service.StudentServiceImpl;

import javax.swing.*;
import java.awt.*;

public class UpdateStudentView extends JDialog {
    JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,20));
    JLabel idLabel = new JLabel("学生编号",JLabel.RIGHT);
    JTextField idTxt = new JTextField();
    JLabel nameLabel = new JLabel("姓名",JLabel.RIGHT);
    JTextField nameTxt = new JTextField();
    JLabel noLabel = new JLabel("学号",JLabel.RIGHT);
    JTextField noTxt = new JTextField();
    JLabel homeLabel = new JLabel("家乡",JLabel.RIGHT);
    JTextField homeTxt = new JTextField();
    JLabel cnLabel = new JLabel("语文成绩",JLabel.RIGHT);
    JTextField cnTxt = new JTextField();
    JLabel mathLabel = new JLabel("数学成绩",JLabel.RIGHT);
    JTextField mathTxt = new JTextField();
    JLabel enLabel = new JLabel("英语成绩",JLabel.RIGHT);
    JTextField enTxt = new JTextField();
    JButton updateBtn = new JButton("修改");

    UpdateStudentViewHandler updateStudentViewHandler;
    public UpdateStudentView(MainView mainView, int selectedStudentId){
        super(mainView,"修改学生",true);


        updateStudentViewHandler = new UpdateStudentViewHandler(this,mainView);
        //查询selectedStudentID对应的记录并回显
        StudentService studentService = new StudentServiceImpl();
        StudentDO selectedStu = studentService.getById(selectedStudentId);
        idLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(idLabel);
        idTxt.setPreferredSize(new Dimension(200,30));
        idTxt.setText(selectedStu.getId() + "");
        //设置id不可编辑
        idTxt.setEnabled(false);
        jPanel.add(idTxt);

        nameLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(nameLabel);
        nameTxt.setPreferredSize(new Dimension(200,30));
        nameTxt.setText(selectedStu.getName());

        jPanel.add(nameTxt);

        noLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(noLabel);
        noTxt.setPreferredSize(new Dimension(200,30));
        noTxt.setText(selectedStu.getNo());

        jPanel.add(noTxt);

        homeLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(homeLabel);
        homeTxt.setPreferredSize(new Dimension(200,30));
        homeTxt.setText(selectedStu.getHomeTown());

        jPanel.add(homeTxt);

        cnLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(cnLabel);
        cnTxt.setPreferredSize(new Dimension(200,30));
        cnTxt.setText(String.valueOf(selectedStu.getCnScore()));
        jPanel.add(cnTxt);

        mathLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(mathLabel);
        mathTxt.setPreferredSize(new Dimension(200,30));
        mathTxt.setText(String.valueOf(selectedStu.getMathScore()));
        jPanel.add(mathTxt);

        enLabel.setPreferredSize(new Dimension(80,30));
        jPanel.add(enLabel);
        enTxt.setPreferredSize(new Dimension(200,30));
        enTxt.setText(String.valueOf(selectedStu.getEnScore()));
        jPanel.add(enTxt);

        updateBtn.addActionListener(updateStudentViewHandler);
        jPanel.add(updateBtn);
        Container contentPane = getContentPane();
        contentPane.add(jPanel);




        setSize(350,500);
        setLocationRelativeTo(null);
        //DISPOSE_ON_CLOSE 只销毁当前的窗体
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
        setVisible(true);

    }
    // 获取修改后的学生对象
    public StudentDO buildUpdateStudentDO() {
        StudentDO studentDO = new StudentDO();
        studentDO.setId(Integer.valueOf(idTxt.getText()));
        studentDO.setName(nameTxt.getText());
        studentDO.setNo(noTxt.getText());
        studentDO.setHomeTown(homeTxt.getText());
        studentDO.setCnScore(Double.valueOf(cnTxt.getText()));
        studentDO.setEnScore(Double.valueOf(enTxt.getText()));
        studentDO.setMathScore(Double.valueOf(mathTxt.getText()));
        return studentDO;
    }
}

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐