在进行数据库设计时,数据库中每一个表对应Java一个实体类,实体类是系统的“人”、“事”、“物”等一些名词,例如图书(Book)就是一个实体类了,实体类Book代码如下:
第一步:编写实体类
//图书实体类 public class Book { // 图书编号 private String bookid; // 图书名称 private String bookname; // 图书作者 private String author; // 出版社 private String publisher; // 出版日期 private String pubtime; // 库存数量 private int inventory; public String getBookid(){ return bookid; } public void setBookid(String bookid){ this.bookid = bookid; } public String getBookname(){ return bookname; } public void setBookname(String bookname){ this.bookname = bookname; } public String getAuthor(){ return author; } public void setAuthor(String author){ this.author = author; } public String getPublisher(){ return publisher; } public void setPublisher(String publisher){ this.publisher = publisher; } public String getPubtime(){ return pubtime; } public void setPubtime(String pubtime){ this.pubtime = pubtime; } public int getInventory() { return inventory; } public void setInventory(int inventory) { this.inventory = inventory; } }
由于这里没有涉及到数据库,这里的数据是JSON文件中的数据,内容如下:
[{"bookid":"0036","bookname": "高等数学", "author":"李放", "publisher":"人民邮电出版社", "pubtime":"20000812","inventory": 1}, {"bookid":"0004","bookname": "FLASH精选","author": "刘扬","publisher": "中国纺织出版社", "pubtime":"19990312", "inventory":2}, {"bookid":"0026", "bookname":"软件工程", "author":"牛田", "publisher":"经济科学出版社", "pubtime": "20000328", "inventory":4}, {"bookid":"0015","bookname": "人工智能","author": "周未", "publisher":"机械工业出版社", "pubtime": "19991223", "inventory":3}, {"bookid":"0032","bookname": "SOL使用手册","author": "贺民","publisher": "电子工业出版社", "pubtime": "19990425", "inventory":2}, {"bookid":"0031","bookname":"python数据分析","author":"张俊红","publisher":"电子工业出版社", "pubtime":"19990426","inventory":10}, {"bookid":"0045","bookname":"深入理解Java虚拟机","author":"周志名","publisher":"机械工业出版社", "pubtime":"20100323","inventory":23}]
从上面可知,整个文档是JSON数组,数组中的每一个元素是JSON对象
第二步:编写解析JSON文档代码:
import org.json.JSONArray; import org.json.JSONObject; import java.io.*; import java.util.ArrayList; import java.util.List; /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/2/25 * @time : 5:33 下午 */ public class HelloWorld { public static void main(String[] args) { List<Book> data = readData(); MyFrameTable myFrameTable = new MyFrameTable("图书库存", data); } // 从文件中读取数据 private static List<Book> readData(){ // 返回的数据列表 List<Book> list = new ArrayList<Book>(); // 数据文件 String file = "/Users/caizhengjie/IdeaProjects/Java学习/src/Swing图形用户界面/图书库存案例/Books.json"; try(FileInputStream fis = new FileInputStream(file); InputStreamReader ir = new InputStreamReader(fis); BufferedReader in = new BufferedReader(ir) ) { // 1.读取文件 StringBuilder stringBuilder = new StringBuilder(); String line = in.readLine(); while (line !=null) { stringBuilder.append(line); line = in.readLine(); } // 2.JSON解码 // 读取JSON字符完成 System.out.println("读取JSON字符完成"); // JSON解码,解码成功返回JSON数组 JSONArray jsonArray = new JSONArray(stringBuilder.toString()); System.out.println("解码JSON字符完成"); // 3.将JSON数组放到List<Book>集合中 // 遍历集合 for (Object item:jsonArray){ JSONObject row = (JSONObject) item; Book book = new Book(); book.setBookid((String) row.get("bookid")); book.setBookname((String) row.get("bookname")); book.setAuthor((String) row.get("author")); book.setPublisher((String) row.get("publisher")); book.setPubtime((String) row.get("pubtime")); book.setInventory((Integer) row.get("inventory")); list.add(book); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return list; } }
上述代码处理过程,经历了三个步骤:主要的过程:
读取文件:通过Java IO取得文件./db/Books.json,每次读取的字符串保存到StringBuilder 的sbuilder对象中。文件读完sbuilder中就是全部的JSON字符串。
JSON解码:读取JSON字符完成后,需要对其进行解码。由于JSON字符串是数组结构,因此解 码时候使用JSONArray,创建JSONArray对象过程就是对字符串进行解码的过程,如果没有发生 异常,说明成功解码。
将JSON数组放到List集合中:本例表格使用的数据格式不是JSON数组形式,而是 List,这种结构就是List集合中每一个元素都是Book类型。这个过程需要遍历JSON数 组,把数据重新组装到Book对象中。
第三步:自定义的表格模型,它继承了抽象类AbstractTableModel类
抽象类 AbstractTableModel要求必须实现getColumnCount()、getRowCount()和getValueAt()三个抽象方法, getColumnCount()方法提供表格列数,getRowCount()方法提供表格的行数,getValueAt()方法提供了指 定行和列时单元格内容。代码getColumnName()方法不是抽象类要求实现的方法,重写该方法能够给表格提供有意义的列名。
import javax.swing.table.AbstractTableModel; import java.util.List; /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/2/25 * @time : 7:30 下午 */ //通过模型创建表格 public class BookTableModel extends AbstractTableModel { // 列名数组 private String[] columnNames = {"书籍编号","书籍名称","作者","出版社","出版日期","库存数量"}; // data保存了表格中的数据,data类型是list集合 private List<Book> data = null; public BookTableModel(List<Book> data){ this.data = data; } //获得行数 @Override public int getRowCount() { return data.size(); } //获得列数 @Override public int getColumnCount() { return columnNames.length; } //获取某行某列的数据 @Override public Object getValueAt(int rowIndex, int columnIndex) { Book book = (Book) data.get(rowIndex); switch (columnIndex){ case 0: return book.getBookid(); case 1: return book.getBookname(); case 2: return book.getAuthor(); case 3: return book.getPublisher(); case 4: return book.getPubtime(); case 5: return book.getInventory(); } return null; } // 获得某列的名字 @Override public String getColumnName(int col){ return columnNames[col]; } }
第四步:编写窗口代码
import java.util.List; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableModel; import java.awt.*; /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @date : 2020/2/25 * @time : 7:47 下午 */ public class MyFrameTable extends JFrame { // 获得当前屏幕的宽和高 private double screenWidth = Toolkit.getDefaultToolkit().getScreenSize().getWidth(); private double screenHight = Toolkit.getDefaultToolkit().getScreenSize().getWidth(); private JTable table; // 图书列表 private List<Book> data; public MyFrameTable(String title, List<Book> data){ super(title); this.data = data; TableModel model = new BookTableModel(data); table = new JTable(model); // 设置表格中内容字体 table.setFont(new Font("微软雅黑",Font.PLAIN,16)); // 设置表列标题字体 table.getTableHeader().setFont(new Font("微软雅黑",Font.BOLD,16)); // 设置行高 table.setRowHeight(40); // 设置为单行选中模式 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // 返回当前行的状态模型 ListSelectionModel rowSM = table.getSelectionModel(); // 注册监听器,选中行发生更改时触发,这里采用匿名内部类 rowSM.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { // 只处理鼠标按下 if (e.getValueIsAdjusting() == false){ return; } ListSelectionModel lsm = (ListSelectionModel) e.getSource(); if (lsm.isSelectionEmpty()){ System.out.println("没有选中行"); } else { int selectedRow = lsm.getMinSelectionIndex(); System.out.println("第"+selectedRow+"行被选中"); } } }); // 创建一个滚动面板jScrollPane JScrollPane jScrollPane = new JScrollPane(); // 把表格添加到滚动面板上 jScrollPane.setViewportView(table); getContentPane().add(jScrollPane,BorderLayout.CENTER); // 设置窗口大小 setSize(960,640); // 计算窗口位于屏幕中心的坐标 int x = (int) (screenWidth-960) /2; int y = (int) (screenHight-960) /2; // 设置窗口位于屏幕中心的坐标 setLocation(x,y); // 设置窗口可见 setVisible(true); } }
运行结果: