要求:
(一)任务描述
(1)编写一个具有图形用户界面的程序,实现对职工基本信息的管理:
A、添加职工信息(职工工号、姓名、出生年月、基本工资、email);
B、显示职工信息:从文件中读取所有职工信息并显示出来;
C、修改和删除职工信息:能对已有职工记录(除工号外)进行修改,能删除已有职工记录,操作能同步到文件中。
D、统计计算:统计职工人数、基本工资平均值、最高工资、最低工资对应的职工的完整信息。
E、程序的主窗口标题要包含开发者的信息“职工信息管理系统,开发者:张三(XXX),指导老师:YYY”,凡是没有加这个信息的,直接扣20分。
F、职工工号由系统自动生成,是一个字符串,格式为XXXXYYZZ,其中XXXX、YY分别为系统当前的年和月,ZZ为职工序号,
例如:20210378表示2021年3月添加的序号为78的工号。
(二)编程要求
(1)添加职工信息时,能对输入的合法性进行检查,以Emai为例,要求用户从文本框中输入的Email必须是合法的Emai,年月也必须是合法的年月。
(2)职工的信息永久存储到文件,若需要显示所有职工及对已有职工记录进行修改,都必须从文件中读写,确保程序退出后信息能得到保存。
(3)以MVC模式进行开发,M为模型,即职工信息模型,它具有职工基本属性,还提供职工数据文件的读写方法,V是添加、删除、修改、浏览等操作的界面,C是事件监听器对象,用来处理界面事件,将模型和视图联系起来,实现数据的存取。
(4)要求各个界面美观、所有窗口打开时居于屏幕正中。
(5)参考方案(你也可以有自己的方案)
可以参考下面的UML图完成类的设计。
成果:
大致类图:(其中的UML类图并不标准,刚学),好分析类与方法
效果图:
具有添加、删除、修改、查找、展示等功能
代码:(因为是写在一个文件下的,所以略显冗杂)
//包
package gui_sy3;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.FlowLayout;
import java.io.BufferedReader;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Test {
//目标文件
final String TARGET_FILE = "./temp.txt";
File targetFile = new File(TARGET_FILE);
public Test() {
JFrame jf = new JFrame("职工信息管理系统");
jf.setSize(300, 300);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel jp0 = new JPanel();
JPanel jp1 = new JPanel();
JPanel jp2 = new JPanel();
JPanel jp3 = new JPanel();
JLabel jl0 = new JLabel();
jl0.setText("职工信息管理系统");
jl0.setFont(new Font(null, Font.PLAIN, 25)); // 设置字体,null 表示使用默认字体
jp0.add(jl0);
JLabel jl1 = new JLabel("开发者:2000300420");
jp1.setLayout(new FlowLayout(FlowLayout.LEFT));
jl1.setFont(new Font(null, Font.PLAIN, 15)); // 设置字体,null 表示使用默认字体
jp1.add(jl1);
JLabel jl2 = new JLabel("指导老师:李*辉");
jp2.setLayout(new FlowLayout(FlowLayout.LEFT));
jl2.setFont(new Font(null, Font.PLAIN, 15)); // 设置字体,null 表示使用默认字体
jp2.add(jl2);
JButton jb0 = new JButton("添加");
JButton jb1 = new JButton("浏览");
jp3.add(jb0);
jp3.add(jb1);
// 添加操作
jb0.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
add();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
// 浏览操作
jb1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
look();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
// 创建一个垂直盒子容器, 把上面 3 个 JPanel 串起来作为内容面板添加到窗口
Box vBox = Box.createVerticalBox();
vBox.add(jp0);
vBox.add(jp1);
vBox.add(jp2);
vBox.add(jp3);
jf.setContentPane(vBox);
// jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
// 添加 -> 窗口
public void add() throws IOException {
JFrame jf = new JFrame("添加职工");
jf.setSize(300, 300);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel jp0 = new JPanel();
JLabel jl0 = new JLabel();
jl0.setText("请输入新员工信息:");
// jl0.setFont(new Font(null, Font.PLAIN, 10)); // 设置字体,null 表示使用默认字体
jp0.setLayout(new FlowLayout(FlowLayout.LEFT));
jp0.add(jl0);
JPanel jp1 = new JPanel();
jp1.add(new JLabel("ID:"));
JTextField jtext1 = new JTextField(10);
jp1.add(jtext1);
JPanel jp2 = new JPanel();
jp2.add(new JLabel("姓名:"));
JTextField jtext2 = new JTextField(10);
jp2.add(jtext2);
JPanel jp3 = new JPanel();
jp3.add(new JLabel("出生年月:"));
JTextField jtext3 = new JTextField(10);
jp3.add(jtext3);
JPanel jp4 = new JPanel();
jp4.add(new JLabel("工资:"));
JTextField jtext4 = new JTextField(10);
jp4.add(jtext4);
JPanel jp5 = new JPanel();
jp5.add(new JLabel("Email:"));
JTextField jtext5 = new JTextField(10);
jp5.add(jtext5);
// 第 3 个 JPanel, 使用浮动布局, 并且容器内组件居中显示
JPanel jp6 = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton jb06 = new JButton("确认添加");
jp6.add(jb06);
if(targetFile.createNewFile()) {
System.out.println("文件不存在,创建成功");
}else {
System.out.println("文件存在");
}
// 添加事件
jb06.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("确认添加");
try {
//打开文件字符输出流
FileWriter writer = new FileWriter(targetFile,true);
//获取文本显示区文本
String[][] result = new String[5][2];
result[0][0] = "ID:";
result[0][1] = jtext1.getText();
result[1][0] = "姓名:";
result[1][1] = jtext2.getText();
result[2][0] = "出生年月:";
result[2][1] = jtext3.getText();
result[3][0] = "工资:";
result[3][1] = jtext4.getText();
result[4][0] = "Email:";
result[4][1] = jtext5.getText();
//写入文件
writer.write("------------\n");
for(int i=0;i<5;i++) {
for(int j=0;j<2;j++) {
writer.write(result[i][j]);
}
writer.write("\n");
}
writer.write("\n");
writer.flush();
//关闭输出流
writer.close();
// 消息对话框无返回, 仅做通知作用
JOptionPane.showMessageDialog(
jf,
"添加成功!",
"添加",
JOptionPane.INFORMATION_MESSAGE
);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
// 创建一个垂直盒子容器, 把上面 3 个 JPanel 串起来作为内容面板添加到窗口
Box vBox = Box.createVerticalBox();
vBox.add(jp0);
vBox.add(jp1);
vBox.add(jp2);
vBox.add(jp3);
vBox.add(jp4);
vBox.add(jp5);
vBox.add(jp6);
jf.setContentPane(vBox);
// jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
// 浏览 -> 窗口
public void look() throws IOException {
JFrame jf = new JFrame("浏览职工信息");
// jf.setSize(300, 300);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 第 1 个 JPanel, 使用默认的浮动布局
JPanel jp0 = new JPanel();
jp0.add(new JLabel("请输入ID "));
JTextField jtext0 = new JTextField(5);
jp0.add(jtext0);
JButton jb0 = new JButton("按ID查找");
jp0.add(jb0);
jp0.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel jp1 = new JPanel();
jp1.add(new JLabel("请输入姓名"));
JTextField jtext1 = new JTextField(5);
jp1.add(jtext1);
JButton jb1 = new JButton("按姓名查找");
jp1.add(jb1);
jp1.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel jp2 = new JPanel();
JButton jb2=new JButton("修改、删除");
jp2.add(jb2);
jp2.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel jp3 = new JPanel();
jp3.add(new JLabel("浏览职工信息,总人数:"));
JButton jb3=new JButton("查看");
jp3.add(jb3);
jp3.setLayout(new FlowLayout(FlowLayout.LEFT));
// // 创建一个 10 行 20 列的文本区域
final JTextArea textArea = new JTextArea(15,30);
// 设置自动换行
textArea.setLineWrap(true);
JScrollPane jsp4 = new JScrollPane(
textArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
);
// 添加到内容面板
// jp4.add(textArea);
// //创建目标文件对象
// targetFile = new File(TARGET_FILE);
// if(targetFile.createNewFile()) {
// System.out.println("文件不存在,创建成功");
// }else {
// System.out.println("文件存在");
// }
// 按ID查找
jb0.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按ID查找");
//获取文本显示区文本
String[][] res = new String[2][2];
res[0][0] = "ID:";
res[0][1] = jtext0.getText();
res[1][0] = "姓名:";
res[1][1] = jtext1.getText();
// 读
FileReader in = null;
try {
in = new FileReader("temp.txt");
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedReader bufIn = new BufferedReader(in);
String line = null;
String[] datas = new String[100];
//读入结果
StringBuffer my_result = new StringBuffer();
int i=0;
int j=0;
try {
while ( (line = bufIn.readLine()) != null) {
datas[i]=line;
i++;
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
if(datas[j].equals(res[0][0]+res[0][1])) {
for(int k=0;k<5;k++) {
my_result.append(datas[j]);
// 添加换行符
my_result.append(System.getProperty("line.separator"));
j++;
}
break;
}
j++;
if(datas[j]==null) {
System.out.println("抱歉,ID未找到!");
break;
}
}
// 关闭 输入流
try {
bufIn.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 更新文本显示区内容
textArea.setFont(new Font("宋体", Font.BOLD, 15));
textArea.setText(my_result.toString());
// 清除框内输入字符
jtext0.setText("");
}
});
// 按姓名查找
jb1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按姓名查找");
//获取文本显示区文本
String[][] res = new String[2][2];
res[0][0] = "ID:";
res[0][1] = jtext0.getText();
res[1][0] = "姓名:";
res[1][1] = jtext1.getText();
// 读
FileReader in = null;
try {
in = new FileReader("temp.txt");
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedReader bufIn = new BufferedReader(in);
String line = null;
String[] datas = new String[100];
// 读入结果
StringBuffer my_result = new StringBuffer();
int i=0;
int j=0;
try {
while ( (line = bufIn.readLine()) != null) {
datas[i]=line;
i++;
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
if(datas[j].equals(res[1][0]+res[1][1])) {
for(int k=0;k<5;k++) {
my_result.append(datas[j-1]);
// 添加换行符
my_result.append(System.getProperty("line.separator"));
j++;
}
break;
}
j++;
if(datas[j]==null) {
System.out.println("抱歉,姓名未找到!");
break;
}
}
// 关闭 输入流
try {
bufIn.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// 更新文本显示区内容
textArea.setFont(new Font("宋体", Font.BOLD, 15));
textArea.setText(my_result.toString());
// 清除框内输入字符
jtext1.setText("");
}
});
// 读出到文本区域事件
jb3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("查看->读出到文本区域事件");
try {
// 字符读入流
FileReader reader = new FileReader(targetFile);
// 读入缓冲区
char[] buffer = new char[1024];
// 读入结果
StringBuffer result = new StringBuffer();
// 每次读入缓冲区的长度
int len;
// 从读入流中读取文件内容并形成结果
while((len = reader.read(buffer)) != -1) {
result.append(buffer,0,len);
}
// 关闭读入流
reader.close();
// 更新文本显示区内容
textArea.setFont(new Font("宋体", Font.BOLD, 15));
textArea.setText(result.toString());
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
// 修改、删除事件
jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
change();
}
});
// 创建一个垂直盒子容器, 把上面 JPanel 串起来作为内容面板添加到窗口
Box vBox = Box.createVerticalBox();
vBox.add(jp0);
vBox.add(jp1);
vBox.add(jp2);
vBox.add(jp3);
vBox.add(jsp4);
jf.setContentPane(vBox);
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
// 修改、删除 -> 窗口
public void change() {
JFrame jf = new JFrame("修改、删除职工信息");
jf.setSize(300, 300);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 第 1 个 JPanel, 使用默认的浮动布局
JPanel jp0 = new JPanel();
jp0.add(new JLabel("ID:"));
JTextField jtext0 = new JTextField(10);
jp0.add(jtext0);
JPanel jp1 = new JPanel();
jp1.add(new JLabel("姓名:"));
JTextField jtext1 = new JTextField(10);
jp1.add(jtext1);
JPanel jp2 = new JPanel();
jp2.add(new JLabel("出生年月:"));
JTextField jtext2 = new JTextField(10);
jp2.add(jtext2);
JPanel jp3 = new JPanel();
jp3.add(new JLabel("工资:"));
JTextField jtext3 = new JTextField(10);
jp3.add(jtext3);
JPanel jp4 = new JPanel();
jp4.add(new JLabel("Email:"));
JTextField jtext4 = new JTextField(10);
jp4.add(jtext4);
JPanel jp5 = new JPanel();
JButton jb51=new JButton("确认修改");
jp5.add(jb51);
JButton jb52=new JButton("确认删除");
jp5.add(jb52);
// 修改事件
jb51.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("确认修改");
//获取文本显示区文本
String[][] result = new String[5][2];
result[0][0] = "ID:";
result[0][1] = jtext0.getText();
result[1][0] = "姓名:";
result[1][1] = jtext1.getText();
result[2][0] = "出生年月:";
result[2][1] = jtext2.getText();
result[3][0] = "工资:";
result[3][1] = jtext3.getText();
result[4][0] = "Email:";
result[4][1] = jtext4.getText();
int found = 0;
String[] datas = new String[100];
FileReader fileReader;
try {
fileReader = new FileReader("temp.txt");
try (BufferedReader buf = new BufferedReader(fileReader)) {
String line = null;
int i=0;
int j=0;
// System.out.println("1");
while((line = buf.readLine() )!= null){
datas[i]=line;
i++;
}
// System.out.println("2");
while(true) {
if(datas[j].equals(result[0][0]+result[0][1])) {
for(int k=0;k<5;k++) {
replacTextContent(datas[j],result[k][0]+result[k][1],j);
j++;
}
found = 1;
break;
}
j++;
if(datas[j]==null) {
JOptionPane.showMessageDialog(
jf,
"未找到!",
"警告",
JOptionPane.WARNING_MESSAGE
);
break;
}
}
// System.out.println("3");
// 消息对话框无返回, 仅做通知作用
if(found == 1) {
JOptionPane.showMessageDialog(
jf,
"修改成功!",
"修改",
JOptionPane.INFORMATION_MESSAGE
);
}
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
// 修改操作 -> 指定行替换txt文件的内容
public void replacTextContent(String oldstr, String newStr, int j) throws IOException{
//原有的内容
String srcStr = oldstr;
//要替换的内容
String replaceStr = newStr;
// 读
FileReader in = new FileReader("temp.txt");
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
int i=0;
while ( (line = bufIn.readLine()) != null) {
if(i==j) {
// 替换每行中, 符合条件的字符串
line = line.replaceAll(srcStr, replaceStr);
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
i++;
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter("temp.txt");
tempStream.writeTo(out);
out.close();
}
});
// 删除事件
jb52.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("确认删除");
//获取文本显示区文本
String[][] result = new String[5][2];
result[0][0] = "ID:";
result[0][1] = jtext0.getText();
result[1][0] = "姓名:";
result[1][1] = jtext1.getText();
result[2][0] = "出生年月:";
result[2][1] = jtext2.getText();
result[3][0] = "工资:";
result[3][1] = jtext3.getText();
result[4][0] = "Email:";
result[4][1] = jtext4.getText();
int found = 0;
String[] datas = new String[100];
FileReader fileReader;
try {
fileReader = new FileReader("temp.txt");
try (BufferedReader buf = new BufferedReader(fileReader)) {
String line = null;
int i=0;
int j=0;
// System.out.println("1");
while((line = buf.readLine() )!= null){
datas[i]=line;
i++;
}
// System.out.println("2");
while(true) {
if(datas[j].equals(result[0][0]+result[0][1])) {
for(int k=0;k<6;k++) {
DeleteTextContent(datas[j-1],j-1);
j++;
}
found = 1;
break;
}
j++;
if(datas[j]==null) {
JOptionPane.showMessageDialog(
jf,
"未找到!",
"警告",
JOptionPane.WARNING_MESSAGE
);
break;
}
}
DeleteText2();
// System.out.println("3");
if(found == 1) {
// 消息对话框无返回, 仅做通知作用
JOptionPane.showMessageDialog(
jf,
"删除成功!",
"删除",
JOptionPane.INFORMATION_MESSAGE
);
}
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
// 删除操作 -> 指定行删除txt文件的内容, 但还有空行
public void DeleteTextContent(String oldstr, int j) throws IOException{
//原有的内容
String srcStr = oldstr;
// 读
FileReader in = new FileReader("temp.txt");
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
int i=0;
while ( (line = bufIn.readLine()) != null) {
if(i==j) {
// 替换每行中, 符合条件的字符串
line = line.replaceAll(srcStr, "");
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
i++;
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter("temp.txt");
tempStream.writeTo(out);
out.close();
}
public void DeleteText2() throws IOException{
// 读
FileReader in = new FileReader("temp.txt");
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
while ( (line = bufIn.readLine()) != null) {
if(line.equals("")) {
continue;
}else{
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter("temp.txt");
tempStream.writeTo(out);
out.close();
}
});
// 创建一个垂直盒子容器, 把上面 JPanel 串起来作为内容面板添加到窗口
Box vBox = Box.createVerticalBox();
vBox.add(jp0);
vBox.add(jp1);
vBox.add(jp2);
vBox.add(jp3);
vBox.add(jp4);
vBox.add(jp5);
// 设置窗口的内容面板
jf.setContentPane(vBox);
// 自动排版
// jf.pack();
/**
* 设置窗口的相对位置。
* 如果 comp 整个显示区域在屏幕内, 则将窗口放置到 comp 的中心;
* 如果 comp 显示区域有部分不在屏幕内, 则将该窗口放置在最接近 comp 中心的一侧;
* comp 为 null, 表示将窗口放置到屏幕中心。
*/
jf.setLocationRelativeTo(null);
// 设置窗口是否可见
jf.setVisible(true);
}
public static void main(String[] args) {
new Test();
}
}