通过在指定路径文件夹内指定名称文件进行遍历 来实现添加 删除 修改的操作
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 }
添加文件类 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 }
导出和导入方法还没写
准备先解决存档问题 用数字id的txt文本读取总感觉有点奇怪 是否该构造个diary类后用配置文件实现呢