JAVA IO阶段作业 每日一记(备忘录) 1.0

发布时间 2023-11-12 23:41:15作者: 风来三醒

通过在指定路径文件夹内指定名称文件进行遍历  来实现添加 删除 修改的操作

Hutool工具类非常好用  省掉了写很多低效且丑陋代码的过程  感谢  爱来自瓷器

 

 

主类  同时也实现了删除操作方法  NoteJFrame

主要逻辑是  如果所选行数不是文件夹内最后一个文件  便将该行后的所有文件名序号减一  同时tabledats的第一列属性  即id也会随之更改

缺点是无法删除多行  而且每次都是隐藏再重新创建该页面  感觉有点不对  应该实现一个刷新方法的?

  1 package com.itheima.ui;
  2 
  3 import cn.hutool.core.io.FileUtil;
  4 import cn.hutool.core.io.file.FileReader;
  5 
  6 import javax.swing.*;
  7 import java.awt.*;
  8 import java.awt.event.ActionEvent;
  9 import java.awt.event.ActionListener;
 10 import java.io.File;
 11 import java.io.FileInputStream;
 12 import java.io.InputStream;
 13 import java.io.ObjectInputStream;
 14 
 15 public class NoteJFrame extends JFrame implements ActionListener {
 16 
 17 
 18     public static int clickn;
 19 
 20     public void setclickNum(int num) {
 21         clickn = num;
 22     }
 23 
 24     public int getclickNum() {
 25         return clickn;
 26     }
 27     //创建三个按钮
 28     JButton add = new JButton("添加");
 29     JButton update = new JButton("修改");
 30     JButton delete = new JButton("删除");
 31 
 32     //创建表格组件
 33     JTable table;
 34 
 35     //创建菜单的导入和导出
 36     JMenuItem exportItem = new JMenuItem("导出");
 37     JMenuItem importItem = new JMenuItem("导入");
 38 
 39     public NoteJFrame() {
 40         //初始化界面
 41         initFrame();
 42         //初始化菜单
 43         initJmenuBar();
 44         //初始化组件
 45         initView();
 46         //让界面显示出来
 47         this.setVisible(true);
 48     }
 49 
 50 
 51 
 52     @Override
 53     public void actionPerformed(ActionEvent e) {
 54         //获取当前那个组件被点击
 55         Object obj = e.getSource();
 56         if (obj == add) {
 57             System.out.println("添加按钮被点击");
 58             this.setVisible(false);
 59             new AddJFrame();
 60 
 61         } else if (obj == update) {
 62             System.out.println("修改按钮被点击");
 63             this.setVisible(false);
 64             int i = table.getSelectedRow();
 65             setclickNum(i);
 66             System.out.println("选中的是第" + i + "行文件");
 67             //i为选择的行数  若 <0 则表示为选中任何行
 68             //那么问题来了  update类怎么得到我选择的行数i数据呢  最后选了通过静态变量传递  点击后就设置static clickNum的值
 69             if (i < 0) {
 70                 showJDialog("没有选中数据");
 71             } else {
 72                 new UpdateJFrame();
 73             }
 74 
 75 
 76         } else if (obj == delete) {
 77             System.out.println("删除按钮被点击");
 78 
 79 
 80             //我也不知道怎么调的  面多了加水  水多了加面  各种定义乱飞  反正调完了
 81             //主要逻辑是  如果所选的行数不是最后一行 将改行后的所有文件名序号-1  同时tabledats的第一列属性即id也会随之更改
 82             int YES = showChooseJDialog();
 83             int i = table.getSelectedRow() + 1;
 84             System.out.println("选中的是第" + i + "行文件");
 85             if (i < 0) {
 86                 showJDialog("没有选中数据");
 87             } else if (i != diaryNum() && YES == 0) {
 88                 File delfile = new File("D:\\aStudy\\代码\\myio2\\diary\\test\\" + i + ".txt");
 89                 System.out.println("删除情况为" + delfile.delete());
 90                 System.out.println("此时文件夹里还剩" + diaryNum() + "-1个文件");
 91                 int nowFile = diaryNum() - 1;
 92                 //i 3   nowFile 4
 93                 for (; i <= nowFile; i++) {
 94                     int tempnum = i + 1;
 95                     File file1 = new File("D:\\aStudy\\代码\\myio2\\diary\\test\\" + tempnum + ".txt");
 96                     String newName = (i + ".txt");
 97                     //用hutool包快捷重命名 不然这里又要写一堆丑陋且低效的代码
 98                     File tempfile = FileUtil.rename(file1,
 99                             newName,
100                             false, false);
101                 }
102                 this.setVisible(false);
103                 new NoteJFrame();
104             }
105 
106         } else if (obj == exportItem) {
107             System.out.println("菜单的导出功能");
108 
109         } else if (obj == importItem) {
110             System.out.println("菜单的导入功能");
111 
112         }
113     }
114 
115 
116     //第一版  直接定义了整个二维数组  发现并不知道如何返回并读取 遂变为返回单个文件 也方便管理
117     public String[][] bgetView() {
118         File file = new File("D:\\aStudy\\代码\\myio2\\diary\\test\\");
119         File[] files = file.listFiles();
120         String[][] tabledatas = new String[2][];
121         int num = 0;
122         if (files != null) {
123             for (File f : files) {
124                 if (f.isFile()) {
125                     num++;
126                     FileReader fr = new FileReader("D:\\aStudy\\代码\\myio2\\diary\\test\\" + diaryNum() + ".txt");
127                     String text = fr.readString();
128                     String title = text.split("\\+")[0];
129                     String content = text.split("\\+")[0];
130                     tabledatas[0][num] = title;
131                     tabledatas[1][num++] = content;
132                 }
133             }
134         }
135         return tabledatas;
136     }
137 
138     //获取当前数字i的diary文件  返回为数组形式
139     public String[] getView(int i) {
140         String[] tabledatas = new String[2];
141         File file = new File("D:\\aStudy\\代码\\myio2\\diary\\test\\" + i + ".txt");
142         FileReader fr = new FileReader(file);
143         String text = fr.readString();
144         String title = text.split("\\+")[0];
145         String content = text.split("\\+")[1];
146         tabledatas[0] = title;
147         tabledatas[1] = content;
148         return tabledatas;
149     }
150 
151     //查询有多少个文件  丑陋 简单 但有效 哈哈
152     public int diaryNum() {
153         File file = new File("D:\\aStudy\\代码\\myio2\\diary\\test");
154         int num = 1;
155         File[] files = file.listFiles();
156         if (files != null) {
157             for (File f : files) {
158                 if (f.isFile())
159                     num++;
160             }
161         }
162         return num;
163     }
164 
165     //初始化组件
166     private void initView() {
167         //定义最上面的每日一记
168         JLabel title = new JLabel("每日一记");
169         title.setBounds(220, 20, 584, 50);
170         title.setFont(new Font("宋体", Font.BOLD, 32));
171         this.getContentPane().add(title);
172 
173         //定义表格的标题
174         Object[] tableTitles = {"编号", "标题", "正文"};
175 
176         int diaryNum = diaryNum();
177         int num = 0;
178         //定义表格的内容
179         //二维数组中的每一个一维数组,是表格里面的一行数据
180 
181         //----------------------
182         //通过循环读取文件夹内文件  实现添加功能
183         Object[][] tabledatas = new Object[diaryNum - 1][3];
184         for (int i = 0; i < diaryNum - 1; i++) {
185             tabledatas[i][0] = ++num;
186             tabledatas[i][1] = getView(num)[0];
187             tabledatas[i][2] = getView(num)[1];
188         }
189                /* {"编号1", "标题1", "正文1"},
190                 {"编号2", "标题2", "正文2"},
191                 {"编号3", "标题3", "正文3"},*/
192 
193         //定义表格组件
194         //并给表格设置标题和内容
195         table = new JTable(tabledatas, tableTitles);
196         table.setBounds(40, 70, 504, 380);
197 
198         //创建可滚动的组件,并把表格组件放在滚动组件中间
199         //好处:如果表格中数据过多,可以进行上下滚动
200         JScrollPane jScrollPane = new JScrollPane(table);
201         jScrollPane.setBounds(40, 70, 504, 380);
202         this.getContentPane().add(jScrollPane);
203 
204         //给三个按钮设置宽高属性,并添加点击事件
205         add.setBounds(40, 466, 140, 40);
206         update.setBounds(222, 466, 140, 40);
207         delete.setBounds(404, 466, 140, 40);
208 
209         add.setFont(new Font("宋体", Font.PLAIN, 24));
210         update.setFont(new Font("宋体", Font.PLAIN, 24));
211         delete.setFont(new Font("宋体", Font.PLAIN, 24));
212 
213         add.addActionListener(this);
214         update.addActionListener(this);
215         delete.addActionListener(this);
216 
217 
218         this.getContentPane().add(add);
219         this.getContentPane().add(update);
220         this.getContentPane().add(delete);
221     }
222 
223     //初始化菜单
224     private void initJmenuBar() {
225         //创建整个的菜单对象
226         JMenuBar jMenuBar = new JMenuBar();
227         //创建菜单上面的两个选项的对象 (功能  关于我们)
228         JMenu functionJMenu = new JMenu("功能");
229 
230         //把5个存档,添加到saveJMenu中
231         functionJMenu.add(exportItem);
232         functionJMenu.add(importItem);
233 
234         //将菜单里面的两个选项添加到菜单当中
235         jMenuBar.add(functionJMenu);
236 
237         //绑定点击事件
238         exportItem.addActionListener(this);
239         importItem.addActionListener(this);
240 
241         //给菜单设置颜色
242         jMenuBar.setBackground(new Color(230, 230, 230));
243 
244         //给整个界面设置菜单
245         this.setJMenuBar(jMenuBar);
246     }
247 
248     //初始化界面
249     private void initFrame() {
250         //设置界面的宽高
251         this.setSize(600, 600);
252         //设置界面的标题
253         this.setTitle("每日一记");
254         //设置界面置顶
255         this.setAlwaysOnTop(true);
256         //设置界面居中
257         this.setLocationRelativeTo(null);
258         //设置关闭模式
259         this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
260         //取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件
261         this.setLayout(null);
262         //设置背景颜色
263         this.getContentPane().setBackground(new Color(212, 212, 212));
264     }
265 
266     //只创建一个弹框对象
267     JDialog jDialog = new JDialog();
268 
269     //因为展示弹框的代码,会被运行多次
270     //所以,我们把展示弹框的代码,抽取到一个方法中。以后用到的时候,就不需要写了
271     //直接调用就可以了。
272     //展示弹框
273     public void showJDialog(String content) {
274         if (!jDialog.isVisible()) {
275             //创建一个弹框对象
276             JDialog jDialog = new JDialog();
277             //给弹框设置大小
278             jDialog.setSize(200, 150);
279             //让弹框置顶
280             jDialog.setAlwaysOnTop(true);
281             //让弹框居中
282             jDialog.setLocationRelativeTo(null);
283             //弹框不关闭永远无法操作下面的界面
284             jDialog.setModal(true);
285 
286             //创建Jlabel对象管理文字并添加到弹框当中
287             JLabel warning = new JLabel(content, 0);
288             warning.setBounds(0, 0, 200, 150);
289             jDialog.getContentPane().add(warning);
290 
291             //让弹框展示出来
292             jDialog.setVisible(true);
293         }
294     }
295 
296     /*
297      *  作用:展示一个带有确定和取消按钮的弹框
298      *
299      *  方法的返回值:
300      *       0 表示用户点击了确定
301      *       1 表示用户点击了取消
302      *       该弹框用于用户删除时候,询问用户是否确定删除
303      * */
304     public int showChooseJDialog() {
305         return JOptionPane.showConfirmDialog(this, "是否删除选中数据?", "删除信息确认", JOptionPane.YES_NO_OPTION);
306     }
307 }
View Code

 

添加文件类  AddJFrame

先读取文件夹内有多少文件  创建文件名为"文件数+1"的新txt  内容读取自文本框中文本

缺点很明显  稳定性非常差  但凡文件夹内文件名错误或不连贯都会导致程序无法运行

也许应该给遍历加个条件?

View Code

 

 

修改文件类  UpdateJFrame

最容易实现的一个类  只是在添加文件类的基础上修改了一下  很多代码都是照抄的

唯一要思考的地方是  如何将选择的行数从主类传给这个类

最后选择的是方法是定义静态关键字和数据

另一个纠结的点是修改后无法同步  查找后发现Hutool工具类中的write方法  有"是否续写"开关

  1 package com.itheima.ui;
  2 
  3 import cn.hutool.core.io.file.FileReader;
  4 import cn.hutool.core.io.file.FileWriter;
  5 
  6 import javax.swing.*;
  7 import java.awt.*;
  8 import java.awt.event.ActionEvent;
  9 import java.awt.event.ActionListener;
 10 import java.io.File;
 11 
 12 public class UpdateJFrame extends JFrame implements ActionListener {
 13     //定义标题输入框
 14     JTextField titleText  = new JTextField();
 15 
 16     //定义内容的输入区域
 17     JTextArea contentText = new JTextArea();
 18 
 19     //定义修改按钮
 20     JButton update = new JButton("修改");
 21 
 22     //定义取消按钮
 23     JButton cancel = new JButton("取消");
 24 
 25     public UpdateJFrame(){
 26         //初始化界面
 27         initFrame();
 28 
 29         //初始化组件
 30         initView();
 31 
 32         //让界面展示出来
 33         this.setVisible(true);
 34     }
 35     public int diaryNum() {
 36         File file = new File("D:\\aStudy\\代码\\myio2\\diary\\test");
 37         int num = 1;
 38         File[] files = file.listFiles();
 39         if (files != null) {
 40             for (File f : files) {
 41                 if (f.isFile())
 42                     num++;
 43             }
 44         }
 45         return num;
 46     }
 47 
 48     @Override
 49     public void actionPerformed(ActionEvent e) {
 50         Object obj = e.getSource();
 51         //此处照抄AddJFrame代码后略微修改
 52         if(obj == update){
 53             System.out.println("修改按钮被点击了");
 54             String title = titleText.getText();
 55             String content = contentText.getText();
 56             int diaryNum = diaryNum()-1;
 57             FileWriter writer = new FileWriter("D:\\aStudy\\代码\\myio2\\diary\\test\\" + diaryNum + ".txt");
 58             writer.write(title + "+" +content,false);
 59             this.setVisible(false);
 60             new NoteJFrame();
 61         }else if(obj == cancel){
 62             System.out.println("取消按钮被点击了");
 63             this.setVisible(false);
 64             new NoteJFrame();
 65         }
 66     }
 67 
 68     private void initView() {
 69         int clickNum = NoteJFrame.clickn + 1 ;
 70         FileReader fr = new FileReader("D:\\aStudy\\代码\\myio2\\diary\\test\\" + clickNum + ".txt");
 71 
 72         //定义最上面的每日一记
 73         JLabel title = new JLabel("每日一记");
 74         title.setBounds(220, 20, 584, 50);
 75         title.setFont(new Font("宋体", Font.BOLD, 32));
 76         this.getContentPane().add(title);
 77 
 78         //定义文字:标题
 79         JLabel subject = new JLabel("标题");
 80         subject.setBounds(70,90,100,30);
 81         subject.setFont(new Font("宋体",Font.PLAIN,16));
 82         this.getContentPane().add(subject);
 83 
 84         //定义文字:内容
 85         JLabel content = new JLabel("内容");
 86         content.setBounds(70,140,100,30);
 87         content.setFont(new Font("宋体",Font.PLAIN,16));
 88         this.getContentPane().add(content);
 89 
 90 
 91         //设置标题的输入框
 92         titleText.setBounds(120,90,426,30);
 93         titleText.setFont(new Font("宋体",Font.PLAIN,16));
 94         this.getContentPane().add(titleText);
 95         //设置标题输入框的预数据
 96         String LastTitle = fr.readString().split("\\+")[0];
 97         titleText.setText(LastTitle);
 98 
 99         //设置内容的输入框
100         contentText.setBounds(120,140,426,300);
101         contentText.setFont(new Font("宋体",Font.PLAIN,16));
102         this.getContentPane().add(contentText);
103         String LastContent = fr.readString().split("\\+")[1];
104         contentText.setText(LastContent);
105 
106         //设置保存按钮
107         update.setBounds(132,466,140,40);
108         update.setFont(new Font("宋体",Font.PLAIN,24));
109         update.addActionListener(this);
110         this.getContentPane().add(update);
111 
112         //设置取消按钮
113         cancel.setBounds(312,466,140,40);
114         cancel.setFont(new Font("宋体",Font.PLAIN,24));
115         cancel.addActionListener(this);
116         this.getContentPane().add(cancel);
117 
118     }
119 
120 
121     //对添加界面的一些设置
122     private void initFrame() {
123         //设置界面的宽高
124         this.setSize(600, 600);
125         //设置界面的标题
126         this.setTitle("每日一记(添加日记)");
127         //设置界面置顶
128         this.setAlwaysOnTop(true);
129         //设置界面居中
130         this.setLocationRelativeTo(null);
131         //设置关闭模式
132         this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
133         //取消默认的居中放置,只有取消了才会按照XY轴的形式添加组件
134         this.setLayout(null);
135         //设置背景颜色
136         this.getContentPane().setBackground(new Color(212,212,212));
137     }
138 }
View Code

 

导出和导入方法还没写 

准备先解决存档问题  用数字id的txt文本读取总感觉有点奇怪  是否该构造个diary类后用配置文件实现呢