Swing-JTable(保存与加载)6/9

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;
		}
	}
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤来实现: 1. 创建一个 JTable 对象,并将其添加到 JFrame 窗口。 2. 使用 JDBC 连接数据库,并编写 SQL 查询语句以检索所需的数据。 3. 将查询结果保存在 ResultSet 对象,并使用 ResultSetMetaData 获取列的名称和数量。 4. 创建一个 DefaultTableModel 对象,并将列名称和数据添加到模型。 5. 将模型设置为 JTable 的数据模型,并使用 setModel() 方法将其设置为 JTable 的模型。 6. 在 JTable 上添加一个按钮列,可以使用 TableColumnModel 和 TableCellRenderer 来实现。 7. 在按钮的 ActionListener 编写代码,以便在单击按钮时执行所需的操作,例如显示所选行的详细信息或删除所选行。 下面是一个简单的示例代码,可以根据需要进行修改: ``` import java.sql.*; import javax.swing.*; import javax.swing.table.*; public class JTableExample extends JFrame { private JTable table; private DefaultTableModel model; public JTableExample() { // 创建 JTable 对象 table = new JTable(); // 创建表头 String[] columns = {"ID", "Name", "Age", "Gender", "Action"}; // 创建数据模型 model = new DefaultTableModel(columns, 0); // 将数据模型设置为 JTable 的模型 table.setModel(model); // 添加按钮列 TableColumnModel columnModel = table.getColumnModel(); columnModel.getColumn(4).setCellRenderer(new ButtonRenderer()); columnModel.getColumn(4).setCellEditor(new ButtonEditor(new JCheckBox())); // 添加 JTable 到 JFrame 窗口 add(new JScrollPane(table)); // 设置窗口属性 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(600, 400); setVisible(true); // 加载数据库数据 loadData(); } public void loadData() { try { // 创建 JDBC 连接 Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", ""); // 创建 SQL 查询语句 String sql = "SELECT * FROM users"; Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(sql); // 获取列的名称和数量 ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); String[] columns = new String[columnCount]; for (int i = 1; i <= columnCount; i++) { columns[i - 1] = metaData.getColumnName(i); } // 添加数据到模型 while (rs.next()) { Object[] rowData = new Object[columnCount + 1]; for (int i = 1; i <= columnCount; i++) { rowData[i - 1] = rs.getString(i); } rowData[columnCount] = "Action"; model.addRow(rowData); } // 关闭 JDBC 连接 rs.close(); stmt.close(); con.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new JTableExample(); } // 自定义按钮列的渲染器 class ButtonRenderer extends JButton implements TableCellRenderer { public ButtonRenderer() { setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setText((value == null) ? "" : value.toString()); return this; } } // 自定义按钮列的编辑器 class ButtonEditor extends DefaultCellEditor { protected JButton button; private String label; private boolean isPushed; public ButtonEditor(JCheckBox checkBox) { super(checkBox); button = new JButton(); button.setOpaque(true); button.addActionListener(e -> fireEditingStopped()); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (isSelected) { button.setForeground(table.getSelectionForeground()); button.setBackground(table.getSelectionBackground()); } else { button.setForeground(table.getForeground()); button.setBackground(table.getBackground()); } label = (value == null) ? "" : value.toString(); button.setText(label); isPushed = true; return button; } public Object getCellEditorValue() { if (isPushed) { // 在这里编写按钮单击后的操作 JOptionPane.showMessageDialog(button, label + " was clicked!"); } isPushed = false; return label; } public boolean stopCellEditing() { isPushed = false; return super.stopCellEditing(); } protected void fireEditingStopped() { super.fireEditingStopped(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值