赞
踩
以上只是我的开发环境,不用刻意关注版本问题,基本都可运行。
字段
准备两个数据库表,一个用于登录验证,一个用于学生信息展示
-- 创建数据库 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操作
设计思路
这里没有输出密码,应该是以用户名为准进行输入,如用户名为空则不输出
登录按钮按键绑定,绑定为人为习惯性的回车键,即点击登录 = 按下 Enter
登录页面大小锁定,无法进行最大化与页面拉伸,这是因为所有组件按钮输入框以及文本框都有计算好屏幕位置,如可拉伸会影响美观,如图:
如果想进行页面拉伸,只需将LoginView
类下的
setResizable(false);
参数改为true
即可!(下方有源码展示)
输入正确的用户名与密码,即我们创建的数据库表manage
中的 user_name
和pwd
字段,即可进入主页面
为了演示我们不占用任务栏位置特色,我们将任务栏换位置进行再次测试如图
注意:这里的动态是指每次程序启动时动态计算屏幕尺寸并铺满屏幕,如果在程序启动途中进行任务栏的改变是无效的,这也是后期需要改进的一点!
当然你也可以极限拖动,显示如下,默认以点显示!缺点是按钮只能进行隐藏,不能进行按钮的缩放,后期看可否改进。
在solyog里面查看,数据添加成功
在数据库这边进行查看,编号为83号
更新成功!
在IDEA中新建一个普通maven项目
新建以下包
如图是我的架构图
在 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
在 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; } }
在包 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; } }
在包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; } }
在包 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 方法
在包 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; } }
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,"添加失败"); } } } }
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,"用户名密码错误"); } } }
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(); } } }
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,"修改失败"); } } } }
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; } }
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); } }
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); } } } }
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; } }
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; } }
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; } }
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(); } }
在第二级包下新建APP
类,用来作为整个启动的起点
package com;
import com.qin.studentview.LoginView;
public class APP {
public static void main(String[] args) {
new LoginView();
}
}
至此,直接启动APP类即可,以上即为所有展示
改进部分
本系统只设立了管理端显示,应该再设立两个学生和教师端,即增加两个用户验证表,增加两个主页面
在动态计算屏幕尺寸并铺满屏幕时,如果在程序启动后再进行任务栏的改变是无效的,这也是需要改进的一点!
在主界面动态拖动,表格可响应式发生变动,但是按钮只能显示或隐藏,无法做到和表格一般响应变大与缩小
在查询中只提供了模糊姓名查询以及精准查询,未提供学号、地址或分数查询
图表功能可结合JFreeChart - 多功能Java图表类库、ECharts-Java - Java版ECharts图表库进行散点、扇形、比例、柱状等多图表绘制,采用web端展示更方便,在swing中会更复杂。
优化部分
// 自定义图标
URL imgUrl = LoginView.class.getClassLoader().getResource("qbt.png");
setIconImage(new ImageIcon(imgUrl).getImage());
可在resource目录下拷贝自己所定义的图片,之后在上述代码中修改文件名即可,上述代码可放置LoginView
中,伴随起始项加载
为了演示,之后会在主界面进行图标更换
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); } }); }
解压jar包,您可以看到我们的起始程序类,jar包依赖,以及版本信息和所需的资源信息,在解压后的META-INF
-> MANIFEST
文件打开进行查看,我们演示用 notepad++ 打开
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; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。