小型圖形化程式需儲存少量資料,用 JDBC 連資料庫過重且慢。改用檔案儲存,並定義為 HTML 表格格式,雙重收益:① 持久化儲存 ② 直接用瀏覽器查看資料。
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class FileWork extends JFrame implements ActionListener {
JPanel p;
JButton btnAdd, btnOpen, btnSave;
JTable table;
Object[][] data = new Object[50][3];
int row = 0;
String[] columns = {"姓名", "年齡", "身高"};
public FileWork() {
super("資料循環");
setSize(300, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel();
table = new JTable(data, columns);
btnAdd = new JButton("添加");
btnOpen = new JButton("打開");
btnSave = new JButton("保存");
btnAdd.addActionListener(this);
btnOpen.addActionListener(this);
btnSave.addActionListener(this);
p.add(btnAdd); p.add(btnOpen); p.add(btnSave);
add(new JScrollPane(table), "Center");
add(p, "South");
setVisible(true);
}
// 打開 HTML 檔案並解析表格資料
void fileOpen() {
try {
JFileChooser chooser = new JFileChooser(".");
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
BufferedReader in = new BufferedReader(new FileReader(chooser.getSelectedFile() + ""));
StringBuilder content = new StringBuilder();
String line;
while ((line = in.readLine()) != null) content.append(line);
in.close();
String html = content.toString();
int[] start = new int[50], end = new int[50];
int k = 0, r = 0;
for (int i = 0; i < 50; i++) {
start[i] = html.indexOf("") + 4;
end[i] = html.indexOf(" ");
if (start[i] > 3 && end[i] > start[i]) {
data[r][k] = html.substring(start[i], end[i]).trim();
html = html.substring(end[i] + 5);
if (++k == 3) { k = 0; r++; }
}
}
row = r;
repaint();
}
} catch (Exception e) { e.printStackTrace(); }
}
// 將 JTable 資料存為 HTML 表格檔案
void fileSave() {
try {
JFileChooser saver = new JFileChooser(".");
if (saver.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(saver.getSelectedFile() + ""));
StringBuilder html = new StringBuilder();
html.append("");
html.append("");
html.append("姓名 年齡 身高 ");
for (int i = 0; i < row; i++) {
html.append("");
html.append("").append(data[i][0]).append(" ");
html.append("").append(data[i][1]).append(" ");
html.append("").append(data[i][2]).append(" ");
html.append(" ");
}
html.append("
");
out.write(html.toString());
out.close();
// 清空介面
for (int i = 0; i < 50; i++) data[i][0] = data[i][1] = data[i][2] = "";
row = 0;
repaint();
JOptionPane.showMessageDialog(null, "保存資料成功!", "Information", JOptionPane.INFORMATION_MESSAGE);
}
} catch (Exception e) { e.printStackTrace(); }
}
// 添加新資料行
void addRow() {
JTextField[] fields = new JTextField[6];
fields[0] = new JTextField("請輸入姓名:"); fields[0].setEditable(false);
fields[1] = new JTextField();
fields[2] = new JTextField("請輸入年齡:"); fields[2].setEditable(false);
fields[3] = new JTextField();
fields[4] = new JTextField("請輸入身高:"); fields[4].setEditable(false);
fields[5] = new JTextField();
String[] opts = {"確認", "取消"};
int ret = JOptionPane.showOptionDialog(null, fields, "添加用戶",
JOptionPane.YES_OPTION, JOptionPane.INFORMATION_MESSAGE, null, opts, opts[0]);
if (ret == 0) {
if (fields[1].getText().isEmpty() && fields[3].getText().isEmpty() && fields[5].getText().isEmpty()) {
JOptionPane.showMessageDialog(null, "資料不能為空", "ERROR", JOptionPane.ERROR_MESSAGE);
} else {
data[row][0] = fields[1].getText();
data[row][1] = fields[3].getText();
data[row][2] = fields[5].getText();
row++;
repaint();
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnOpen) fileOpen();
else if (e.getSource() == btnSave) fileSave();
else if (e.getSource() == btnAdd) addRow();
}
public static void main(String[] args) {
new FileWork();
}
}
| 優點 | 缺點 |
|---|---|
| 零資料庫依賴,部署極簡 | 不適合大量資料/高併發 |
| HTML 可直接瀏覽器開啟,人眼可讀 | 查詢/索引需自行實現,效能弱 |
| 適合小型工具、設定檔、日誌導出 | 無交易支援,資料一致性靠自律 |
適用場景:桌面小工具、離線資料收集、測試資料導出、教學示範專案。