学生信息管理系统(控制台版)
改造基于CSV的小程序为GUI版本:
基于CSV文件的学生信息管理系统:实现一个基于Swing的学生信息的添加、删除、修改、查询操作
CSV: 逗号分隔文件,例如:
name,sex,age,idcard,adress
张三,男,13,13412341234,龙子湖校区
扩展:用table组件做
JTable 存取数据,面向对象Student传递数据
package studentSystem;
public class Student {
private String stuNum;//学号
private String name;//姓名
private String gender;//性别
private String age;//年龄
private String loc;//地址
public Student()
{
}
public Student(String name, String gender, String age, String stuNum, String loc){
this.name = name;
this.gender = gender;
this.age = age;
this.stuNum = stuNum;
this.loc = loc;
}
public String getStuNum()
{
return stuNum;
}
public void pushStuNum(String stuNum)
{
this.stuNum = stuNum;
}
public String getName()
{
return name;
}
public void pushName(String name)
{
this.name = name;
}
public String getGender()
{
return gender;
}
public void pushGender(String gender)
{
this.gender = gender;
}
public String getAge()
{
return age;
}
public void pushAge(String age)
{
this.age = age;
}
public String getLoc()
{
return loc;
}
public void pushLoc(String loc)
{
this.loc = loc;
}
}
package studentSystem;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
public class myDemo {
public static void main(String[] args) throws IOException {
//主窗体名称设置,同时初始化插入设计的窗口
JFrame frame = new myFrame("Student System");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1600,1200);//窗口尺寸设置
centerInScreen(frame);//函数实现窗口位置居中
frame.setVisible(true);//显示主窗口
}
//实现主窗口在屏幕中央出现
private static void centerInScreen(Window win) {
//new对象获得屏幕尺寸数据
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x = (screenSize.width - win.getWidth()) / 2;
int y = (screenSize.height - win.getHeight()) / 2;
//设置窗口位置
win.setLocation(x, y);
}
}
根容器使用BordLayout(边框布局)
实现各种操作的按钮放在BordLayout.NORTH
全部数据放在BordLayout.CENTER的表格里
通过查找找到的数据展示在BorderLayout.SOUTH的表格里
效果展示:
JTable jtb = new JTable();// BordLayout.CENTER表格,展示文件中的全部数据
JTable jtbS = new JTable();//BordLayout.SOUTH表格,展示搜索出的数据
//BordLayout.CENTER的表格数据模型,储存中心表格的数据
public static DefaultTableModel jtbModel = new DefaultTableModel();
//BordLayout.SOUTH的表格数据模型,储存搜索出的符合条件的数据
public DefaultTableModel jtbModel1 = new DefaultTableModel();
//指定删除的文本输入框
public JTextField AdelField = new JTextField();
//指定修改的文本输入框
public JTextField selectField = new JTextField();
private JComponent initCenter()
{
//设置组件为可见
jtb.setFillsViewportHeight(true);
//设置表格行高
jtb.setRowHeight(50);
//引入对应的表格模型
jtb.setModel(this.jtbModel);
//表格各列表头设置
jtbModel.addColumn("姓名");
jtbModel.addColumn("性别");
jtbModel.addColumn("年龄");
jtbModel.addColumn("学号");
jtbModel.addColumn("地址");
//返回包含中心表格的JScrollPane
return new JScrollPane(jtb);
}
private JComponent initTop()
{
//创建一个panel组件,储存BordLayout.NORTH的各组件,采用流式布局
JPanel panel1 = new JPanel();
//采用流式布局
panel1.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 10));
//设置两个文本框的大小
AdelField.setPreferredSize(new Dimension(200,30));
selectField.setPreferredSize(new Dimension(200,30));
//创建BordLayout.NORTH的各个按钮
JButton addButton = new JButton("添加");
JButton delButton = new JButton("删除");
JButton saveButton = new JButton("保存");
JButton selectButton = new JButton("查询");
JButton AdelButton = new JButton("指定删除");
JButton AreviseButton = new JButton("指定修改");
//将BordLayout.NORTH的各组件添加到panel容器中
panel1.add(saveButton);
panel1.add(addButton);
panel1.add(delButton);
panel1.add(AreviseButton);
panel1.add(selectField);
panel1.add(selectButton);
panel1.add(AdelField);
panel1.add(AdelButton);
//以下是各按钮的监听器
//添加按钮的监听器
addButton.addActionListener((e)->{
onAdd();
});
//删除按钮的监听器
delButton.addActionListener((e)->{
onDel();
});
//保存按钮的监听器
saveButton.addActionListener((e)->{
try {
onSave();
} catch (IOException ex) {
ex.printStackTrace();
}
});
//搜索按钮的监听器
selectButton.addActionListener((e)->{
try {
onSelect();
} catch (IOException ex) {
ex.printStackTrace();
}
});
//指定删除的监听器
AdelButton.addActionListener((e)->{
onADel();
});
//指定修改的修改器
AreviseButton.addActionListener((e)->{
try {
onArevise();
} catch (IOException ex) {
ex.printStackTrace();
}
});
//返回BordLayout
return panel1;
}
private JComponent initSouth()
{
//设置表格显示
jtbS.setFillsViewportHeight(true);
//设置表格行高
jtbS.setRowHeight(50);
//把储存搜索出的符合条件的数据的表格模型插入表格
jtbS.setModel(jtbModel1);
//设置表格列头
jtbModel1.addColumn("姓名");
jtbModel1.addColumn("性别");
jtbModel1.addColumn("年龄");
jtbModel1.addColumn("学号");
jtbModel1.addColumn("地址");
//返回存有表格的JScrollPane
return new JScrollPane(jtbS);
}
####### 3.4 myFrame 的构造函数
public myFrame(String title) throws IOException {
super(title);
//根容器的创建
JPanel root = new JPanel();
//根容器采用边框布局
root.setLayout(new BorderLayout());
//将根容器插入
this.setContentPane(root);
//将根容器的各个部分插入其中
root.add(initTop(), BorderLayout.NORTH);
root.add(initCenter(), BorderLayout.CENTER);
root.add(initSouth(), BorderLayout.SOUTH);
//从文件中读取数据到BordLayout.CENTER的表格
FileInputStream fcin = new FileInputStream("F:\\Student\\StudentData.csv");
InputStreamReader inr = new InputStreamReader(fcin, "GB2312");
BufferedReader br = new BufferedReader(inr);
//创建数组来接受从文件中读取的数据
String line = "";
String[] arrs;
for(int i = 0; (line=br.readLine())!=null; i ++) {
arrs=line.split(",");
//以学生类为中介传递文件中的数据到JTable中
Student a = new Student();
a.pushName(arrs[0].trim());
a.pushGender(arrs[1].trim());
a.pushAge(arrs[2].trim());
a.pushStuNum(arrs[3].trim());
a.pushLoc(arrs[4].trim());
//自己实现的用来向表格中插入一行数据的函数
addRow(a);
}
//依次关闭流,先开后关,后开先关
br.close();
inr.close();
fcin.close();
}
private void addRow(Student item)
{
//创建一个可变数组用来做向表格模型中传数据的桥梁
Vector<Object> rowData = new Vector<>();
//向可变数组中插入数据
rowData.add(item.getName());
rowData.add(item.getGender());
rowData.add(item.getAge());
rowData.add(item.getStuNum());
rowData.add(item.getLoc());
//将可变数组中的数据插入表格模型
jtbModel.addRow(rowData);
}
private void addRow1(Student item)
{
Vector<Object> rowData = new Vector<>();
rowData.add(item.getName());
rowData.add(item.getGender());
rowData.add(item.getAge());
rowData.add(item.getStuNum());
rowData.add(item.getLoc());
jtbModel1.addRow(rowData);
}
保存
添加
删除
指定修改
查询
指定删除
onAdd函数通过实现一个InputDialog类,实现弹出窗口,输入信息后,并保存的功能
//InputDialog类的实现
package studentSystem;
import javax.swing.*;
import java.awt.*;
public class InputDialog extends JDialog {
//创建插入窗口的各输入框
public JTextField nameField = new JTextField();
public JTextField ageField = new JTextField();
public JTextField sexField = new JTextField();
public JTextField stuNumField = new JTextField();
public JTextField locField = new JTextField();
private boolean accepted = false;
public InputDialog( Window owner )
{
super ( owner );
//定义输入文本框的大小
nameField.setPreferredSize(new Dimension(400,30));
ageField.setPreferredSize(new Dimension(400,30));
sexField.setPreferredSize(new Dimension(400,30));
stuNumField.setPreferredSize(new Dimension(400,30));
locField.setPreferredSize(new Dimension(400,30));
//创建容器将各组件加入其中
JPanel root = new JPanel();
this.setContentPane( root );
root.setLayout( new BorderLayout());
root.add( initCenter(), BorderLayout.CENTER);
root.add( initBottom(), BorderLayout.SOUTH);
root.add( initNorth(), BorderLayout.NORTH);
}
//顶部,标题
private JComponent initNorth()
{
//“添加”窗口的标题设置
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
JLabel label = new JLabel("请填写所要添加的成员信息");
label.setFont(new Font("微软雅黑",Font.BOLD, 25));
panel.add(label);
return panel;
}
// 中央,表单 字段
private JComponent initCenter()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add( createField("姓名: ", nameField));
panel.add( createField("性别: ", sexField));
panel.add( createField("年龄: ", ageField));
panel.add( createField("学号: ", stuNumField));
panel.add( createField("地址: ", locField));
return panel;
}
// 表单 字段
private JComponent createField(String lable0, JComponent comp)
{
//CENTER文本输入框格式设置
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JLabel label = new JLabel(lable0);
label.setFont(new Font("微软雅黑",Font.BOLD, 18));
panel.add(label);
panel.add(comp);
return panel;
}
// 底部,操作按钮
private JComponent initBottom()
{
//底部操作按钮的格式设置
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT, 20, 20));
JButton okButton = new JButton("确定");
panel.add(new JLabel(), "1w");
panel.add( okButton);
//确定后弹出确认对话框二次确认后继续操作
okButton.addActionListener((e)->{
accepted = true;
setVisible ( false ); // 关闭对话框
});
return panel;
}
// 显示对话框
public boolean exec()
{
this.setTitle("添加");
this.setModal( true ); // 模态的,即阻塞模式
this.setSize(600, 400);
this.centerInOwner();//在程序中央弹出
// 显示对话框,并阻塞等待
this.setVisible( true ); // 显示对话框,并阻塞
return accepted ; // accepted为true时,表示用户点了确定。为false时表示用户取消了操作。
}
//确保“添加”窗口出现在上层窗口正中
private void centerInOwner()
{
Rectangle ownerRect = this.getOwner().getBounds();
int width = this.getWidth();
int height = this.getHeight();
int x = ownerRect.x + (ownerRect.width - width) / 2;
int y = ownerRect.y + (ownerRect.height - height) / 2;
this.setBounds(x, y, width, height);
}
// 取得用户的输入
public Student getValue()
{
//创建学生类对象接受各文本输入框的输入内容
Student value = new Student();
value.pushName(nameField.getText());
value.pushGender(sexField.getText().trim());
value.pushAge(ageField.getText());
value.pushStuNum(stuNumField.getText().trim());
value.pushLoc(locField.getText());
//校验输入的年龄是否为数字
for(char i: value.getAge().toCharArray())
{
if(i < '0' || i > '9')
{
JOptionPane.showMessageDialog(this, "年龄只能是数字!");
return null;
}
}
//校验输入的学号位数是否为10
if(value.getStuNum().length() != 10)
{
JOptionPane.showMessageDialog(this, "学号位数错误!");
return null;
}
//校验学号是否为纯数字
for(char i: value.getStuNum().toCharArray())
{
if(i < '0' || i > '9')
{
JOptionPane.showMessageDialog(this, "学号只能是数字!");
return null;
}
}
//校验性别是否为“男”或“女”
if(!value.getGender().trim().equals("男") && !value.getGender().trim().equals("女"))
{
JOptionPane.showMessageDialog(this, "性别信息错误!");
return null;
}
return value;
}
// 通过该函数从类中获得添加的学生档案信息
public void setValue(Student value)
{
nameField.setText( value.getName());
sexField.setText(value.getGender());
ageField.setText(value.getAge());
stuNumField.setText(value.getStuNum());
locField.setText( value.getLoc());
}
}
/*----------------我是InputDialog类和onAdd函数的分割线-------------------------------*/
//MyFrame类内onAdd的实现
private void onAdd()
{
InputDialog dlg = new InputDialog(this);
//创建一个InputDialog对象然后调用函数插入数据
if(dlg.exec())
{
//通过getValue函数获得输入的学生数据
Student value = dlg.getValue();
//若输入不为空,则存入中心表格中
if(value != null)
{
addRow(value);
JOptionPane.showMessageDialog(this, "学生档案信息已储存!");
}
}
}
private void onDel()
{
//创建整形数组接受所选中的行数
int[] rows = jtb.getSelectedRows();
//确定后弹出确认对话框二次确认后继续操作
int select = JOptionPane.showConfirmDialog(this,
"是否确认删除?",
"确认",
JOptionPane.YES_NO_OPTION);
// select 为用户点的第几个按钮
if(select == 0)
{
for(int i = rows.length - 1 ; i >= 0; i --)
{
int index = rows[i];
jtbModel.removeRow(index);
}
}
}
//向文件中写入数据
private void onSave() throws IOException{
FileOutputStream fout = new FileOutputStream("F:\\Student\\StudentData.csv");
OutputStreamWriter ouw = new OutputStreamWriter(fout, "GB2312");
BufferedWriter bw = new BufferedWriter(ouw);
//将操作过的数据一行一行的存入String数组arrs并写入文件
for(int i = 0; i < jtbModel.getRowCount(); i ++)
{
String[] arrs = new String[5];
arrs[0] = String.valueOf(jtbModel.getValueAt(i,0));
arrs[1] = String.valueOf(jtbModel.getValueAt(i,1));
arrs[2] = String.valueOf(jtbModel.getValueAt(i,2));
arrs[3] = String.valueOf(jtbModel.getValueAt(i,3));
arrs[4] = String.valueOf(jtbModel.getValueAt(i,4));
bw.write(arrs[0] + "," + arrs[1] + ","+ arrs[2] + ","+ arrs[3] + ","+ arrs[4] + "\n");
}
//按找打开流的顺序,先开后关,后开先关
bw.close();
ouw.close();
fout.close();
JOptionPane.showMessageDialog(this, "学生档案信息已储存!");
}
//AreviseDialog类的实现
package studentSystem;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
public class AreviseDialog extends JDialog {
public JTextField AstuNumField = new JTextField();
public JTextField nameField = new JTextField();
public JTextField ageField = new JTextField();
public JTextField sexField = new JTextField();
public JTextField stuNumField = new JTextField();
public JTextField locField = new JTextField();
private boolean accepted = false;
public AreviseDialog(Window owner) throws IOException {
super ( owner );
//定义输入文本框的大小
AstuNumField.setPreferredSize(new Dimension(400,30));
nameField.setPreferredSize(new Dimension(400,30));
ageField.setPreferredSize(new Dimension(400,30));
sexField.setPreferredSize(new Dimension(400,30));
stuNumField.setPreferredSize(new Dimension(400,30));
locField.setPreferredSize(new Dimension(400,30));
//创建容器将各组件加入其中
JPanel root = new JPanel();
this.setContentPane(root);
root.setLayout(new BorderLayout());
root.add( initCenter(), BorderLayout.CENTER);
root.add( initBottom(), BorderLayout.SOUTH);
root.add( initNorth(), BorderLayout.NORTH);
}
//顶部,标题
private JComponent initNorth()
{
//“指定修改”窗口的标题格式设置
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
JLabel label = new JLabel("请填写所要修改学生档案的学号");
label.setFont(new Font("微软雅黑",Font.BOLD, 25));
panel.add(label);
return panel;
}
// 中央,表单 字段
private JComponent initCenter()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add( createField("所要修改档案的学号: ", AstuNumField));
panel.add( new JLabel(" "));
panel.add( createField("姓名: ", nameField));
panel.add( createField("性别: ", sexField));
panel.add( createField("年龄: ", ageField));
panel.add( createField("学号: ", stuNumField));
panel.add( createField("地址: ", locField));
return panel;
}
// 表单 字段
private JComponent createField(String lable0, JComponent comp)
{
//CENTER文本输入框格式设置
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JLabel label = new JLabel(lable0);
label.setFont(new Font("微软雅黑",Font.BOLD, 18));
panel.add(label);
panel.add(comp);
return panel;
}
// 底部,操作按钮
private JComponent initBottom()
{
//底部操作按钮格式设置
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT, 20, 20));
JButton okButton = new JButton("确定");
panel.add(new JLabel(), "1w");
panel.add( okButton);
//确定后弹出确认对话框二次确认后继续操作
okButton.addActionListener((e)->{
int select = JOptionPane.showConfirmDialog(this,
"是否确认修改?",
"确认",
JOptionPane.YES_NO_OPTION);
if(select == 0)
{
onOk();
setVisible ( false );
}
});
return panel;
}
//myFrame中通过调用该函数来弹出窗口,同时根据此函数返回值确定是否完成二次确定
public boolean option()
{
this.setTitle("修改指定学生档案信息");
this.setModal( true ); // 模态的,即阻塞模式
this.setSize(850, 500);
this.centerInOwner();//在程序中央弹出
// 显示对话框,并阻塞等待
this.setVisible( true ); // 显示对话框,并阻塞
return accepted;
}
//使得弹出的窗口出现在上层窗口的中间
private void centerInOwner()
{
Rectangle ownerRect = this.getOwner().getBounds();
int width = this.getWidth();
int height = this.getHeight();
int x = ownerRect.x + (ownerRect.width - width) / 2;
int y = ownerRect.y + (ownerRect.height - height) / 2;
this.setBounds(x, y, width, height);
}
// 取得用户的输入
public Student getValue()
{
Student value = new Student();
value.pushName(nameField.getText());
value.pushGender(sexField.getText());
value.pushAge(ageField.getText());
value.pushStuNum(stuNumField.getText());
value.pushLoc(locField.getText());
return value;
}
//实现窗口下侧确定按钮的监听
public void onOk()
{
//根据获得的消息判断是否修改学生档案,并返回提示消息
for(int i = 0; i < myFrame.jtbModel.getRowCount(); i ++)
{
if(String.valueOf(myFrame.jtbModel.getValueAt(i,3)).equals(stuNumField.getText()))
{
accepted = true;
myFrame.jtbModel.removeRow(i);
JOptionPane.showMessageDialog(this, "已修改指定学生档案");
return;
}
}
JOptionPane.showMessageDialog(this, "查无此人");
}
}
//myFrame类内onArevise()函数实现
private void onArevise() throws IOException {
AreviseDialog dlg = new AreviseDialog(this);
if(dlg.option())
{
//修改指定学生档案
Student value = dlg.getValue();
addRow(value);
}
}
private void onSelect() throws IOException {
//查询前将查询表格清空
for(int i = jtbModel1.getRowCount() - 1; i >= 0; i --)
{
jtbModel1.removeRow(i);
}
/*根据按钮前文本框中输入内容,分别以学号和姓名为索引在主表格中进行遍历,来实现准确搜索,找到后则将其
加入到查询表格中,展示查询结果*/
for(int i = 0; i < jtbModel.getRowCount(); i ++)
{
if(String.valueOf(myFrame.jtbModel.getValueAt(i,0)).equals(selectField.getText()))
{
Student value = new Student();
value.pushName(String.valueOf(myFrame.jtbModel.getValueAt(i,0)));
value.pushGender(String.valueOf(myFrame.jtbModel.getValueAt(i,1)));
value.pushAge(String.valueOf(myFrame.jtbModel.getValueAt(i,2)));
value.pushStuNum(String.valueOf(myFrame.jtbModel.getValueAt(i,3)));
value.pushLoc(String.valueOf(myFrame.jtbModel.getValueAt(i,4)));
addRow1(value);
}
else if(String.valueOf(myFrame.jtbModel.getValueAt(i,3)).equals(selectField.getText()))
{
Student value = new Student();
value.pushName(String.valueOf(myFrame.jtbModel.getValueAt(i,0)));
value.pushGender(String.valueOf(myFrame.jtbModel.getValueAt(i,1)));
value.pushAge(String.valueOf(myFrame.jtbModel.getValueAt(i,2)));
value.pushStuNum(String.valueOf(myFrame.jtbModel.getValueAt(i,3)));
value.pushLoc(String.valueOf(myFrame.jtbModel.getValueAt(i,4)));
addRow1(value);
}
}
//如果两轮遍历均未找到,则表明该表格中没有相应学生数据,展示提示消息
if(jtbModel1.getRowCount() == 0)
{
JOptionPane.showMessageDialog(this, "查无此人");
}
}
private void onADel() {
//删除需要二次确认
int select = JOptionPane.showConfirmDialog(this,
"是否确认删除?",
"确认",
JOptionPane.YES_NO_OPTION);
// select 为用户点的第几个按钮
if(select == 0)
{
//遍历表格对比学号,如果有指定学号,则删除指定档案
for(int i = 0; i < myFrame.jtbModel.getRowCount(); i ++)
{
if(String.valueOf(myFrame.jtbModel.getValueAt(i,3)).equals(AdelField.getText()))
{
jtbModel.removeRow(i);
JOptionPane.showMessageDialog(this, "已删除指定学生档案");
return;
}
}
JOptionPane.showMessageDialog(this, "查无此人");
}
}
我是@荒诞丶学家,水平有限,不过觉得文章不错的话,不妨点个赞关注下!