需求文档来自黑马程序员微信公众号学习资源百度网盘资源
项目界面:
当前项目设计三个界面:
- 主界面
程序启动时打开的界面
- 添加界面
添加日记时打开的界面
- 修改界面
修改日记时打开的界面
业务逻辑:
主界面逻辑:
第一次启动游戏时,主界面中什么都没有,如下图所示:
添加界面逻辑:
点击添加时候,出现添加界面,如下图所示,可以在添加界面中输入标题和内容。
填完之后点击保存:回到主界面中,并将刚刚添加数据同步到主界面
如果在添加界面,点击取消:也回到主界面,但是刚刚添加的数据舍弃不要
修改界面逻辑:
主界面中直接点击修改,弹框提示:未选中要修改的行,请重试
主界面中,先选中要修改的行,再点击修改,则进入修改界面,如下图所示:
点击修改,修改成功回到主界面
点击取消,不修改内容回到主界面
删除逻辑:
主界面中直接点击删除,弹框提示:未选中要修改的行,请重试
主界面中,先选中要修改的行,再点击删除,提示是否删除选中数据
点击是:删除成功
点击否:删除失败
附加需求:
在主界面添加一个菜单,菜单中有两个选项,一个是导出一个是导入
点击导出时,将所有日记文件打包成压缩包放到桌面上压缩包名为data.zip
点击导入时,默认将桌面上的data.zip压缩包解压,获取里面所有的数据展示出来
实现:
一、日记类
package cn.edu.gxufe.entity;
import java.io.Serializable;
// 日记对象
public class Daily implements Serializable {
private static final long serialVersionUID = -3731209612900218877L;
private int ID; // 编号
private String title; // 标题
private String content; // 内容
public Daily() {
}
public Daily(int ID, String title, String content) {
this.ID = ID;
this.title = title;
this.content = content;
}
/**
* 获取
* @return ID
*/
public int getID() {
return ID;
}
/**
* 设置
* @param ID
*/
public void setID(int ID) {
this.ID = ID;
}
/**
* 获取
* @return title
*/
public String getTitle() {
return title;
}
/**
* 设置
* @param title
*/
public void setTitle(String title) {
this.title = title;
}
/**
* 获取
* @return content
*/
public String getContent() {
return content;
}
/**
* 设置
* @param content
*/
public void setContent(String content) {
this.content = content;
}
public String toString() {
return "Daily{ID = " + ID + ", title = " + title + ", content = " + content + "}";
}
}
二、主界面
package cn.edu.gxufe.ui;
import cn.edu.gxufe.entity.Daily;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
// 每日一记主界面
public class NoteJFrame extends JFrame implements ActionListener {
// 无参构造方法
public NoteJFrame() {
// 初始化每日一记主界面
initFrame();
// 初始化界面菜单
initJMenuBar();
// 初始化界面组件
initView();
// 将界面显示出来
this.setVisible(true);
}
// 创建表格对象
JTable table;
// 创建添加、修改、删除三个按钮对象
JButton insert = new JButton("添加");
JButton update = new JButton("修改");
JButton delete = new JButton("删除");
// 创建二维数组,用于存储表格中的每一行数据
public static Object[][] tableDatas = null;
// 初始化界面组件
private void initView() {
// 1.设置大标题:每日一记
// 创建JLabel容器用于管理文字:每日一记
JLabel title = new JLabel("每日一记");
// 设置大标题的坐标位置
title.setBounds(265, 20, 500, 40);
// 设置大标题的字体样式
title.setFont(new Font("宋体", Font.BOLD, 32));
// 将大标题:每日一记放到界面的隐藏容器中
this.getContentPane().add(title);
// 2.设置表格
// 创建一维数组,用于存储表格的标题
Object[] tableTitles = {"编号", "标题", "正文"};
tableDatas = new Object[10000][3];
// 设置表格内容及坐标
table = new JTable(tableDatas, tableTitles);
table.setBounds(90, 70, 500, 500);
//创建可滚动的组件,并把表格组件放在滚动组件中间
//好处:如果表格中数据过多,可以进行上下滚动
JScrollPane jScrollPane = new JScrollPane(table);
jScrollPane.setBounds(90, 70, 500, 400);
this.getContentPane().add(jScrollPane);
// 3.读取日记对象
// 创建日记存储文档的文件夹对象
File file = new File("daily\\data");
getFileDatas(file);
// 3.设置添加、修改、删除三个按钮的坐标与宽高、字体样式
insert.setBounds(90, 500, 100, 40);
update.setBounds(290, 500, 100, 40);
delete.setBounds(490, 500, 100, 40);
insert.setFont(new Font("宋体", Font.PLAIN, 24));
update.setFont(new Font("宋体", Font.PLAIN, 24));
delete.setFont(new Font("宋体", Font.PLAIN, 24));
// 给三个按钮绑定点击事件
insert.addActionListener(this);
update.addActionListener(this);
delete.addActionListener(this);
// 将添加、修改、删除三个按钮放进界面的隐藏容器中
this.getContentPane().add(insert);
this.getContentPane().add(update);
this.getContentPane().add(delete);
}
/**
* 获取文件夹中的所有文件数据
*
* @param src 数据源文件路径
*/
private void getFileDatas(File src) {
// 得到文件夹下所有的日记存储文档的数组
File[] files = src.listFiles();
// 遍历数组,依次得到所有日记文档的路径
for (int i = 0; i < files.length; i++) {
// 判断是文件还是文件夹
if (files[i].isFile()) {
// 是文件
try {
// 依次与每一个日记文档建立连接管道
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(files[i]));
// 依次读取每一个日记文档(返回一个反序列化的日记对象)
Daily daily = (Daily) ois.readObject();
// 关闭流
ois.close();
// 依次给二维数组中的每一个一维数组添加元素(添加行数据)
tableDatas[i][0] = daily.getID();
tableDatas[i][1] = daily.getTitle();
tableDatas[i][2] = daily.getContent();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
} else {
// 是文件夹:递归
getFileDatas(files[i]);
}
}
}
// 创建功能的导入和导出
JMenuItem importItem = new JMenuItem("导入");
JMenuItem exportItem = new JMenuItem("导出");
// 初始化界面菜单
private void initJMenuBar() {
// 创建整个的菜单对象
JMenuBar jMenuBar = new JMenuBar();
// 创建菜单下的选项对象:功能
JMenu functionJMenu = new JMenu("功能");
// 将导入和导出这两个栏目放进功能菜单下
functionJMenu.add(importItem);
functionJMenu.add(exportItem);
// 将功能菜单放进整个的菜单中
jMenuBar.add(functionJMenu);
// 给导入和导出绑定点击事件
importItem.addActionListener(this);
exportItem.addActionListener(this);
// 给菜单设置背景颜色
jMenuBar.setBackground(new Color(197, 197, 197));
// 将菜单设置到界面中
this.setJMenuBar(jMenuBar);
}
// 初始化每日一记主界面
private void initFrame() {
// 设置界面的宽高
this.setSize(700, 700);
// 设置界面的标题
this.setTitle("每日一记");
// 设置界面置顶
this.setAlwaysOnTop(true);
// 设置界面居中
this.setLocationRelativeTo(null);
// 设置关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 取消默认的居中位置,只有取消了才会按照x、y轴的形式添加组件
this.setLayout(null);
// 设置界面的背景颜色
this.getContentPane().setBackground(new Color(204, 238, 200));
}
// 监听点击事件
@Override
public void actionPerformed(ActionEvent e) {
// 获取当前被点击的对象
Object obj = e.getSource();
// 判断是哪个组件对象被点击了
if (obj == insert) {
System.out.println("添加按钮被点击");
// 关闭当前界面后,跳转到添加日记的界面
this.setVisible(false);
new AddJFrame();
} else if (obj == update) {
System.out.println("修改按钮被点击");
// 情况1:如果没有选中某条数据,直接点击修改,则提示:未选中要修改的行,请重试
// 获取选中的是哪条数据:二维数组中元素的索引
int i = table.getSelectedRow();
// 如果i小于0
if (i < 0) {
showJDialog("daily\\images\\gantanhao.png", "未选中要修改的行~ 请重试!");
return;
}
// 情况2:如果选中了某条数据,但是是空的,则提示:已没有可修改的行,请重试
Object daily = tableDatas[i][0];
if (daily == null) {
showJDialog("daily\\images\\gantanhao.png", "该行没有数据可修改~ 请重试!");
return;
}
// 情况3:如果选中了某条数据,是存在的,则关闭当前界面后,跳转到修改日记的界面
this.setVisible(false);
// 传递被选中的日记的编号给修改构造方法
new UpdateJFrame((int) daily);
} else if (obj == delete) {
System.out.println("删除按钮被点击");
// 情况1:如果没有选中某条数据,直接点击删除,则提示:未选中要删除的行,请重试
int i = table.getSelectedRow();
// 如果i小于0
if (i < 0) {
showJDialog("daily\\images\\gantanhao.png", "未选中要删除的行~ 请重试!");
return;
}
// 情况2:如果选中了某条数据,但是是空的,则提示:已没有可删除的行,请重试
Object daily = tableDatas[i][0];
if (daily == null) {
showJDialog("daily\\images\\gantanhao.png", "该行没有数据可删除~ 请重试!");
return;
}
// 情况3:如果选中了某条数据,点击删除后,提示:是否要删除选中的数据
// 获取被选中的日记文档的序号
int ID = (int) daily;
// 弹出一个提示框
int num = showChooseJDialog();
// 如果选择是,则删除,否则不做任何操作
if (num == 0) {
// 删除
File file = new File("daily\\data\\data" + ID + ".txt");
file.delete();
// 刷新主界面
this.setVisible(false);
new NoteJFrame();
}
} else if (obj == importItem) {
System.out.println("导入功能被点击");
// 解压文件夹
// 点击导入时,默认将桌面上的data.zip压缩包解压,获取里面所有的数据展示出来
// 1.创建File对象src,表示要解压的压缩包
File src = new File("C:\\Users\\吴先生\\Desktop\\data.zip");
// 2.创建File对象dest,表示解压后的文件的去处
File dest = new File("E:\\JavaDevelop\\code01\\javase_consolidation_exercise\\daily\\");
// 3.判断src路径是否不存在
if (!src.exists()) {
showJDialog("daily\\images\\gantanhao.png", "data.zip不存在~ 请重试!");
return;
}
try {
// 4.解压
unzip(src, dest);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else if (obj == exportItem) {
System.out.println("导出功能被点击");
// 压缩文件夹(压缩流)
// 需求:点击导出时,将所有日记文件打包成压缩包放到桌面上压缩包名为data.zip
// 0.判断是否没有日记可以导出
if (tableDatas[0][0] == null) {
showJDialog("daily\\images\\gantanhao.png", "没有日记可以导出~ 请重试!");
return;
}
// 1.创建File对象表示要压缩的文件夹
File src = new File("daily\\data");
// 2.创建File对象表示文件夹压缩后放在哪里
File dest = new File("C:\\Users\\吴先生\\Desktop\\");
// 3.创建File对象表示压缩包的路径
File zipSrc = new File(dest, src.getName() + ".zip");
try {
// 4.创建压缩流关联压缩包
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipSrc));
// 5.将指定文件夹下的所有文件进行压缩
toZip(src, zos, src.getName());
// 关闭流
zos.close();
showJDialog("成功导出所有日记到电脑桌面");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
/**
* 解压zip格式的压缩包
*
* @param src 数据源:要解压的压缩包
* @param dest 目的地:解压后文件或文件夹的去处
*/
private void unzip(File src, File dest) throws IOException {
// 解压本质:把压缩包里面的每一个文件或文件夹读取出来,按照层级拷贝到目的地中
// 1.创建一个解压缩流对象,用于读取压缩包中的数据
ZipInputStream zip = new ZipInputStream(new FileInputStream(src));
/*// 获取压缩包文件名(包括后缀)
String srcName = src.getName();
// 2.创建目的地目录
File destDir = new File(dest, srcName.substring(0, srcName.indexOf(".")));
destDir.mkdirs();*/
// 3.要先获取到压缩包中的每一个ZipEntry对象
// 表示在当前压缩包中获取到的文件或文件夹
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
// 3.判断zipEntry是否为文件夹
if (entry.isDirectory()) {
// 文件夹:需要在目的地dest处创建一个同样的文件夹
File file = new File(dest, entry.toString());
file.mkdirs();
} else {
// 文件:需要读取到压缩包中的文件,并将该文件存放到目的地dest文件夹中(按照层级目录进行存放)
FileOutputStream fos = new FileOutputStream(new File(dest, entry.toString()));
// 按照1个字节数组读取文件中的数据
byte[] suffer = new byte[4096];
int len;
while ((len = zip.read(suffer)) != -1) {
// 写到目的地
fos.write(suffer, 0, len);
}
fos.close();
// 表示在压缩包中的一个文件处理完毕了!
zip.closeEntry();
}
}
// 压缩包中所有的文件或文件夹处理完毕!关闭
zip.close();
// 刷新主界面
this.setVisible(false);
new NoteJFrame();
}
/**
* 将文件夹打包成一个压缩包
*
* @param src 要压缩的文件夹
* @param zos 压缩流
* @param name 压缩包内部的路径
*/
private void toZip(File src, ZipOutputStream zos, String name) throws IOException {
// 压缩本质:把每一个文件或文件夹放到压缩包中
// 1.判断要压缩的文件夹路径是否不存在
if (!src.exists()) {
showJDialog("daily\\images\\gantanhao.png", "该路径不存在~ 请重试!");
return;
}
// 2.获取所有文件或文件夹
File[] files = src.listFiles();
// 3.遍历files数组,依次得到每一个文件或文件夹
for (File file : files) {
// 判断file是否为文件
if (file.isFile()) {
// 是文件:将该文件变成ZipEntry对象,并放到压缩包中
ZipEntry entry = new ZipEntry(name + "\\" + file.getName());
zos.putNextEntry(entry);
// 依次读取每一个文件的数据,写入到压缩包中
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) != -1) {
zos.write(buffer, 0, len);
}
// 关闭流
fis.close();
// 表示一个文件已处理完毕
zos.closeEntry();
}
}
}
/*
因为展示弹框的代码,会被运行多次
所以,我们把展示弹框的代码,抽取到一个方法中。以后用到的时候,就不需要写了
直接调用就可以了。
展示弹框
*/
private void showJDialog(String path, String content) {
//创建一个弹框对象
JDialog jDialog = new JDialog();
//给弹框设置大小
jDialog.setSize(270, 150);
//让弹框置顶
jDialog.setAlwaysOnTop(true);
//让弹框居中
jDialog.setLocationRelativeTo(null);
//弹框不关闭永远无法操作下面的界面
jDialog.setModal(true);
//创建JLabel对象管理图片并添加到弹框当中
JLabel warningIma = new JLabel();
warningIma.setBounds(165, -25, 200, 150);
warningIma.setIcon(new ImageIcon(path));
jDialog.getContentPane().add(warningIma);
//创建JLabel对象管理文字并添加到弹框当中
JLabel warning = new JLabel(content);
warning.setBounds(0, 0, 200, 150);
jDialog.getContentPane().add(warning);
//让弹框展示出来
jDialog.setVisible(true);
}
// 展示弹框
private void showJDialog(String content) {
//创建一个弹框对象
JDialog jDialog = new JDialog();
//给弹框设置大小
jDialog.setSize(270, 150);
//让弹框置顶
jDialog.setAlwaysOnTop(true);
//让弹框居中
jDialog.setLocationRelativeTo(null);
//弹框不关闭永远无法操作下面的界面
jDialog.setModal(true);
//创建JLabel对象管理文字并添加到弹框当中
JLabel warning = new JLabel(content);
warning.setBounds(0, 0, 200, 150);
jDialog.getContentPane().add(warning);
//让弹框展示出来
jDialog.setVisible(true);
}
/*
* 作用:展示一个带有确定和取消按钮的弹框
*
* 方法的返回值:
* 0 表示用户点击了确定
* 1 表示用户点击了取消
* 该弹框用于用户删除时候,询问用户是否确定删除
* */
public int showChooseJDialog() {
return JOptionPane.showConfirmDialog(this, "是否删除选中数据?", "删除信息确认", JOptionPane.YES_NO_OPTION);
}
}
三、添加日记界面
package cn.edu.gxufe.ui;
import cn.edu.gxufe.entity.Daily;
import cn.hutool.core.io.IoUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
// 添加日记界面
public class AddJFrame extends JFrame implements ActionListener {
public AddJFrame() {
// 初始化添加日记界面
initFrame();
// 初始化界面组件
initView();
// 将界面显示出来
this.setVisible(true);
}
// 创建标题输入框
JTextField titleText = new JTextField();
// 创建正文内容的输入区域
JTextArea contentText = new JTextArea();
// 创建保存和取消按钮
JButton save = new JButton("保存");
JButton cancel = new JButton("取消");
// 初始化界面组件
private void initView() {
// 1.设置大标题:每日一记
// 创建JLabel容器用于管理文字:每日一记
JLabel title = new JLabel("每日一记");
// 设置大标题的坐标位置
title.setBounds(265, 20, 500, 40);
// 设置大标题的字体样式
title.setFont(new Font("宋体", Font.BOLD, 32));
// 将大标题:每日一记放到界面的隐藏容器中
this.getContentPane().add(title);
// 2.设置文字:标题
JLabel subject = new JLabel("标题");
subject.setBounds(70, 70, 100, 30);
subject.setFont(new Font("宋体", Font.PLAIN, 16));
this.getContentPane().add(subject);
// 设置标题的输入框
titleText.setBounds(120, 70, 430, 30);
titleText.setFont(new Font("微软雅黑", Font.PLAIN, 16));
this.getContentPane().add(titleText);
// 3.设置文字:内容
JLabel content = new JLabel("内容");
content.setBounds(70, 130, 100, 30);
content.setFont(new Font("宋体", Font.PLAIN, 16));
this.getContentPane().add(content);
// 设置内容的输入区域
contentText.setBounds(120, 130, 430, 350);
contentText.setFont(new Font("微软雅黑", Font.PLAIN, 16));
this.getContentPane().add(contentText);
// 4.设置保存和取消按钮
save.setBounds(120, 520, 100, 40);
save.setFont(new Font("宋体", Font.PLAIN, 24));
save.addActionListener(this);
this.getContentPane().add(save);
cancel.setBounds(445, 520, 100, 40);
cancel.setFont(new Font("宋体", Font.PLAIN, 24));
cancel.addActionListener(this);
this.getContentPane().add(cancel);
}
// 初始化添加日记界面
private void initFrame() {
// 设置界面的宽高
this.setSize(700, 700);
// 设置界面的标题
this.setTitle("每日一记(添加日记)");
// 设置界面置顶
this.setAlwaysOnTop(true);
// 设置界面居中
this.setLocationRelativeTo(null);
// 设置关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 取消默认的居中位置,只有取消了才会按照x、y轴的形式添加组件
this.setLayout(null);
// 设置界面的背景颜色
this.getContentPane().setBackground(new Color(204, 238, 200));
}
// 监听点击事件
@Override
public void actionPerformed(ActionEvent e) {
// 获取当前被点击的组件对象
Object obj = e.getSource();
// 判断当前被点击的是哪个组件对象
if (obj == save) {
System.out.println("保存按钮被点击");
// 如果数组的最后一个日记对象不为空,那就说明二维数组存满了
// 保存添加的内容到本地文件
try {
// 创建日记存储文档的文件夹对象
File file = new File("daily\\data");
// 得到文件夹下所有的日记存储文档的数组
File[] files = file.listFiles();
// 如果文件夹下没有日记文件,说明现在写的是第一个日记
if (files.length == 0) {
// 与日记文档建立连接管道(特别的:第一个新文件名的序号1)
ObjectOutputStream bw = new ObjectOutputStream(new FileOutputStream("daily\\data\\data" + 1 + ".txt"));
// 将输入框的标题和内容封装成一个日记对象写到本地文件中(特别的:第一个新日记的编号1)
Daily daily = new Daily(1, titleText.getText(), contentText.getText());
// 利用糊涂包将序列化的日记对象写入到本地文件中
IoUtil.writeObjects(bw, true, daily);
// 关闭流
bw.close();
}else {
// 将最后一个日记文件的路径转换成字符串
String str = files[files.length - 1] + "";
// 截取最后一个日记文件的序号
int ID = str.charAt(15) - '0';
// 与日记文档建立连接管道(特别的:新文件名的序号就是最后一个文件名的序号 +1)
ObjectOutputStream bw = new ObjectOutputStream(new FileOutputStream("daily\\data\\data" + (ID + 1) + ".txt"));
// 将输入框的标题和内容封装成一个日记对象写到本地文件中(特别的:新日记的编号就是最后一个日记的编号 +1)
Daily daily = new Daily(ID + 1, titleText.getText(), contentText.getText());
// 利用糊涂包将序列化的日记对象写入到本地文件中
IoUtil.writeObjects(bw, true, daily);
// 关闭流
bw.close();
}
// 关闭当前界面回到主界面
this.setVisible(false);
new NoteJFrame();
} catch (IOException ex) { // 捕获异常
throw new RuntimeException(ex);
}
} else if (obj == cancel) {
System.out.println("取消按钮被点击");
// 关闭当前界面回到主界面
this.setVisible(false);
new NoteJFrame();
}
}
}
四、修改日记界面
package cn.edu.gxufe.ui;
import cn.edu.gxufe.entity.Daily;
import cn.hutool.core.io.IoUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
// 修改日记界面
public class UpdateJFrame extends JFrame implements ActionListener {
// 日记的编号
int ID;
public UpdateJFrame(int ID) {
this.ID = ID;
// 初始化修改日记界面
initFrame();
// 初始化界面组件
initView();
// 将界面显示出来
this.setVisible(true);
}
// 创建标题输入框
JTextField titleText = new JTextField();
// 创建正文内容的输入区域
JTextArea contentText = new JTextArea();
// 创建修改和取消按钮
JButton update = new JButton("修改");
JButton cancel = new JButton("取消");
// 保存当前被选中的日记文档的路径
String path;
// 定义空日记对象
Daily daily;
// 初始化界面组件
private void initView() {
// 1.设置大标题:每日一记
// 创建JLabel容器用于管理文字:每日一记
JLabel title = new JLabel("每日一记");
// 设置大标题的坐标位置
title.setBounds(265, 20, 500, 40);
// 设置大标题的字体样式
title.setFont(new Font("宋体", Font.BOLD, 32));
// 将大标题:每日一记放到界面的隐藏容器中
this.getContentPane().add(title);
// 2.设置文字:标题
JLabel subject = new JLabel("标题");
subject.setBounds(70, 70, 100, 30);
subject.setFont(new Font("宋体", Font.PLAIN, 16));
this.getContentPane().add(subject);
// 设置标题的输入框
titleText.setBounds(120, 70, 430, 30);
titleText.setFont(new Font("微软雅黑", Font.PLAIN, 16));
this.getContentPane().add(titleText);
// 3.设置文字:内容
JLabel content = new JLabel("内容");
content.setBounds(70, 130, 100, 30);
content.setFont(new Font("宋体", Font.PLAIN, 16));
this.getContentPane().add(content);
// 设置内容的输入区域
contentText.setBounds(120, 130, 430, 350);
contentText.setFont(new Font("微软雅黑", Font.PLAIN, 16));
this.getContentPane().add(contentText);
// 4.设置保存和取消按钮
update.setBounds(120, 520, 100, 40);
update.setFont(new Font("宋体", Font.PLAIN, 24));
update.addActionListener(this);
this.getContentPane().add(update);
cancel.setBounds(445, 520, 100, 40);
cancel.setFont(new Font("宋体", Font.PLAIN, 24));
cancel.addActionListener(this);
this.getContentPane().add(cancel);
// 记录该日记文档的路径
path = "daily\\data\\data" + ID + ".txt";
// 反序列化得到该日记文档对象
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
daily = (Daily) ois.readObject();
ois.close();
titleText.setText(daily.getTitle());
contentText.setText(daily.getContent());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
// 将数据显示到标题输入框、内容区域
}
// 初始化修改日记界面
private void initFrame() {
// 设置界面的宽高
this.setSize(700, 700);
// 设置界面的标题
this.setTitle("每日一记(修改日记)");
// 设置界面置顶
this.setAlwaysOnTop(true);
// 设置界面居中
this.setLocationRelativeTo(null);
// 设置关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// 取消默认的居中位置,只有取消了才会按照x、y轴的形式添加组件
this.setLayout(null);
// 设置界面的背景颜色
this.getContentPane().setBackground(new Color(204, 238, 200));
}
// 监听点击事件
@Override
public void actionPerformed(ActionEvent e) {
// 获取当前被点击的组件对象
Object obj = e.getSource();
// 判断当前被点击的是哪个组件对象
if (obj == update) {
System.out.println("修改按钮被点击");
try {
// 保存修改后的内容到本地文件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
// 将输入框的内容封装成日记对象并写到本地文件中
IoUtil.writeObjects(oos, true,
new Daily(daily.getID(), titleText.getText(), contentText.getText()));
oos.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
// 关闭当前界面回到主界面
this.setVisible(false);
new NoteJFrame();
} else if (obj == cancel) {
System.out.println("取消按钮被点击");
// 关闭当前界面回到主界面
this.setVisible(false);
new NoteJFrame();
}
}
}
五、启动入口
import cn.edu.gxufe.ui.AddJFrame;
import cn.edu.gxufe.ui.NoteJFrame;
import cn.edu.gxufe.ui.UpdateJFrame;
public class App {
public static void main(String[] args) {
// 程序启动入口
new NoteJFrame();
// new AddJFrame();
// new UpdateJFrame();
}
}
六、测试
添加日记:
修改日记:
删除日记:
导出日记(将所有日记文件压缩成一个压缩包):
导入日记(将电脑桌面的data.zip压缩包中的所有文件解压出来):