在Swing-JTable(删除记录)5/9的基础上,这里使用JSON来进行数据的保存与修改
package swing03;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.io.File;
import java.net.URL;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.json.JSONArray;
import org.json.JSONObject;
public class MyFrame extends JFrame {
// Model:负责数据
DefaultTableModel tableModel = new DefaultTableModel();
// View:负责显示,创建JTable的时候指定一个Model
JPanel root = new JPanel();
JTable table = null;
public MyFrame(String title) {
super(title);
this.setContentPane(root);
root.setLayout(new BorderLayout());
//表格初始化
initTable();
//初始化工具栏
initToolBar();
//加载文件
loadData();
}
private void initTable()
{
//创建JTable,直接重写isCellEditable(),设为不可编辑
table=new JTable(tableModel) {
@Override
public boolean isCellEditable(int row, int column) {
// TODO Auto-generated method stub
return false;
}
};
// 添加至滚动面板
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true);// 确保表永远不会小于视图区
table.setRowSelectionAllowed(true);// 整行选择
table.setRowHeight(30);
root.add(scrollPane, BorderLayout.CENTER);
// 初始化设置
tableModel.addColumn("学号");
tableModel.addColumn("姓名");
tableModel.addColumn("性别");
tableModel.addColumn("出生日期");
tableModel.addColumn("手机号");
// 列设置自定义绘制
table.getColumnModel().getColumn(2).setCellRenderer(new SexColumnRenderer());
table.getColumnModel().getColumn(0).setCellRenderer(new IDColumnRenderer());
table.getColumnModel().getColumn(0).setPreferredWidth(110);
}
//
private void addTableRow(Student stu) {
// 方法01
// import java.util.Vector是个泛型,表示数组
// Vector<Object>rowData=new Vector<>();
// rowData.add(stu.id);
// rowData.add(stu.name);
// rowData.add(stu.sex);
// rowData.add(stu.birthday);
// rowData.add(stu.cellphone);
// tableModel.addRow(rowData);
// 方法2
Object[] rowData = new Object[5];
rowData[0] = stu.id;
rowData[1] = stu.name;
rowData[2] = stu.sex;
rowData[3] = stu.birthday;
rowData[4] = stu.cellphone;
tableModel.addRow(rowData);
}
private void initToolBar()
{
JToolBar toolBar=new JToolBar();
root.add(toolBar, BorderLayout.PAGE_START);
toolBar.setFloatable(false);
//添加按钮
JButton addButton=createToolButton("添加","ic_add.png");
toolBar.add(addButton);
toolBar.addSeparator();
addButton.addActionListener((e)->{
showAddDialog();
});
// 删除按钮
JButton deleteButton = createToolButton("删除", "ic_delete.png" );
toolBar.add(deleteButton);
deleteButton.addActionListener( (e)->{
onDelete();
});
}
private JButton createToolButton(String buttonName,String iconName)
{
//图标
String imagePath="/icons/"+iconName;
URL imageURL=getClass().getResource(imagePath);
//创建按钮
JButton button=new JButton(buttonName);
button.setToolTipText(buttonName);
button.setIcon(new ImageIcon(imageURL));
//button.setFocusPainted(false);
return button;
}
//添加数据
private void showAddDialog()
{
EditStudentDialog dlg=new EditStudentDialog(this);
if( dlg.exec() )
{
Student stu=dlg.getValue();
addTableRow( stu);
}
saveData();//保存到文件
}
//点击删除按钮
private void onDelete()
{
//获取选中的行的索引
int[] rows=table.getSelectedRows();
if(rows.length==0)return ;
//弹出对话框
int select=JOptionPane.showConfirmDialog(this, "是否确认删除?", "确认", JOptionPane.YES_NO_OPTION);
if(select!=0)return; //"0"是确定按钮
//技巧:从后往前删除
for(int i=rows.length-1;i>=0;i--)
{
tableModel.removeRow(rows[i]);
}
saveData();
}
//保存数据
private void saveData()
{
//构造一个JSON数组
JSONArray array=new JSONArray();
for(int i=0;i<tableModel.getRowCount();i++)
{
JSONObject j1=new JSONObject();
j1.put("id", tableModel.getValueAt(i, 0));
j1.put("name", tableModel.getValueAt(i, 1));
j1.put("sex", tableModel.getValueAt(i, 2));
j1.put("birthday", tableModel.getValueAt(i, 3));
j1.put("cellphone", tableModel.getValueAt(i, 4));
array.put(j1);
}
//将JSON对象保存到文件
File file=new File("students.json");
try {
JsJSON.toFile(array, file, "utf-8");
} catch (Exception e) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(this, e.getMessage());
e.printStackTrace();
}
}
private void loadData()
{
//加载文件
File file=new File("students.json");
if(!file.exists())return;
JSONArray array=null;
try {
array=(JSONArray)JsJSON.fromFile(file, "utf-8");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage());
e.printStackTrace();
return;
}
//显示到表格
tableModel.setRowCount(0);//清空
for(int i=0;i<array.length();i++)
{
JSONObject j1=array.getJSONObject(i);
Student s=new Student();
s.id=j1.getString("id");
s.name=j1.getString("name");
s.sex=j1.getBoolean("sex");
s.cellphone=j1.getString("cellphone");
s.birthday=j1.getString("birthday");
addTableRow(s);
}
}
}
JSJSON
package swing03;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.json.JSONArray;
import org.json.JSONObject;
public class JsJSON
{
// json: 可以是JSONObject 或 JSONArray
// encoding: "UTF-8", "GBK"
public static void toFile(Object json, File file, String encoding) throws Exception
{
String jsonstr = null;
if(json instanceof JSONObject)
jsonstr = ((JSONObject)json).toString(2);
else if(json instanceof JSONArray)
jsonstr = ((JSONArray)json).toString(2);
else
throw new Exception("Must be org.json.JSONObject or org.json.JSONArray");
// 存入文件
OutputStream outputStream = new FileOutputStream(file);
try {
// UTF-8写入BOM头部
encoding=encoding.toUpperCase();
if(encoding.equals("UTF-8"))
{
byte[] bom = { (byte)0xEF, (byte)0xBB,(byte) 0xBF };
outputStream.write(bom);
}
byte[] data = jsonstr.getBytes(encoding);
outputStream.write(data);
}finally {
// 确保文件被关闭
try { outputStream.close();} catch(Exception e) {}
}
}
public static Object fromFile(File file, String encoding) throws Exception
{
InputStream inputStream = new FileInputStream(file);
try {
int fileSize = (int)file.length();
byte[] data = new byte[fileSize];
int n = inputStream.read(data);
int offset = 0;
encoding=encoding.toUpperCase();
if(n > 3 && encoding.equals("UTF-8"))
{
if(data[0] == (byte)0xEF && data[1]==(byte)0xBB && data[2] == (byte)0xBF)
offset = 3; // 前3个字节是BOM
}
String jsonstr = new String(data, offset, n-offset, encoding);
// 找第一个非空白字符, 从而判断它是JSONObject 还是JSONArray
char firstChar = ' ';
for(int i=0; i<jsonstr.length(); i++)
{
firstChar = jsonstr.charAt(i);
if(firstChar != ' ' && firstChar != '\t' && firstChar != '\n' && firstChar != '\r')
break;
}
// 如果以{开头,则转成JSONObject; 如果以[开头,则转成 JSONArray
if(jsonstr.startsWith("{") )
{
return new JSONObject( jsonstr );
}
else if(jsonstr.startsWith("[") )
{
return new JSONArray ( jsonstr);
}
else
{
throw new Exception("JSON must begin with { or [ !");
}
}finally {
try {inputStream.close();} catch(Exception e) {}
}
}
//
// 在JSONObject里已经有了现成的方法, 以opt开头的方法都是带默认值的
// JSONObject.optInt()
// JSONObject.optLong()
// JSONObject.optString()
// JSONObject.optBoolean()
// ... 注 :以下方法重复,不需要了 ... 带缺省值得get方法
// 相当于 JSONObject.optInt()
public static int getInt (JSONObject json, String key, int defValue)
{
try {
return json.getInt(key);
}catch(Exception e)
{
return defValue;
}
}
// 相当于 JSONObject.optLong()
public static long getLong (JSONObject json, String key, long defValue)
{
try {
return json.getLong(key);
}catch(Exception e)
{
return defValue;
}
}
// 相当于 JSONObject.optString()
public static String getString (JSONObject json, String key, String defValue)
{
try {
return json.getString(key);
}catch(Exception e)
{
return defValue;
}
}
// 相当于 JSONObject.optBoolean()
public static boolean getBoolean (JSONObject json, String key, boolean defValue)
{
try {
return json.getBoolean(key);
}catch(Exception e)
{
return defValue;
}
}
}