首先,我永远不会序列化 DefaultTableModel,否则你会序列化你不想序列化的东西,包括侦听器等等。最好保持简单,并序列化数据,并且只序列化数据。我将序列化包含感兴趣数据的数据向量。用它来用检索到的数据重建一个新的表模型。
幸运的是 DefaultTableModel 有一个方法 .getDataVector() 从模型中检索 Vector<Vector> 来保存模型中的所有数据。如果您必须使用序列化,我会使用它来保存和检索数据。
在下面的代码中,我有一个扩展 DefaultTableModel 的简单类,它允许使用数据向量重新创建模型,使用常量向量来保存表格标题:
class MyModel extends DefaultTableModel {
public static final String[] HEADERS = { "One", "Two", "Three" };
public static final Vector<String> V_HEADERS = new Vector<>(Arrays.asList(HEADERS));
public MyModel(Vector<Vector<Object>> data) {
super(data, V_HEADERS);
}
public MyModel() {
super(HEADERS, 0);
}
}
然后我可以通过此代码对模型持有的数据进行序列化和反序列化以进行序列化:
// assuming that the model is held in a variable called "myModel"
Vector tableData = myModel.getDataVector();
// file name is held by DATA_FILE String constant
try (FileOutputStream fos = new FileOutputStream(DATA_FILE);
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(tableData); // writes my data
} catch (IOException ioe) {
ioe.printStackTrace(); // always catch and handle exceptions
}
我可以将数据读回模型,然后通过以下方式读入 JTable:
// again DATA_FILE is our file's name
try (FileInputStream fis = new FileInputStream(DATA_FILE);
ObjectInputStream ois = new ObjectInputStream(fis)) {
// read the data vector in with the ObjectInputStream
Vector<Vector<Object>> tableData = (Vector<Vector<Object>>) ois.readObject();
// create a new table model with the data
myModel = new MyModel(tableData);
// set the JTable with the new model
table.setModel(myModel);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
一个工作示例:
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class Gui01 extends JPanel {
public static final String DATA_FILE = "tableData.dat";
private MyModel myModel = new MyModel();
private JTable table = new JTable(myModel);
public Gui01() {
int maxRow = 5;
for (int row = 0; row < maxRow; row++) {
Vector<Object> rowData = new Vector<>();
for (int col = 0; col < table.getColumnCount(); col++) {
Integer cell = row * table.getColumnCount() + col;
rowData.add(cell);
}
myModel.addRow(rowData);
}
saveTable();
JButton saveTableBtn = new JButton("Save Table");
saveTableBtn.setMnemonic(KeyEvent.VK_S);
saveTableBtn.addActionListener(e -> saveTable());
JButton clearTableBtn = new JButton("Clear Table");
clearTableBtn.setMnemonic(KeyEvent.VK_C);
clearTableBtn.addActionListener(e -> clearTable());
JButton retrieveTableBtn = new JButton("Retrieve Table");
retrieveTableBtn.setMnemonic(KeyEvent.VK_R);
retrieveTableBtn.addActionListener(e -> retrieveTable());
JPanel buttonPanel = new JPanel();
buttonPanel.add(saveTableBtn);
buttonPanel.add(clearTableBtn);
buttonPanel.add(retrieveTableBtn);
setLayout(new BorderLayout());
add(new JScrollPane(table));
add(buttonPanel, BorderLayout.PAGE_END);
}
@SuppressWarnings("rawtypes")
private void saveTable() {
Vector tableData = myModel.getDataVector();
try (FileOutputStream fos = new FileOutputStream(DATA_FILE);
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(tableData);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private void clearTable() {
myModel.setRowCount(0);
}
@SuppressWarnings("unchecked")
private void retrieveTable() {
try (FileInputStream fis = new FileInputStream(DATA_FILE);
ObjectInputStream ois = new ObjectInputStream(fis)) {
Vector<Vector<Object>> tableData = (Vector<Vector<Object>>) ois.readObject();
myModel = new MyModel(tableData);
table.setModel(myModel);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
Gui01 mainPanel = new Gui01();
JFrame frame = new JFrame("Gui01");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
class MyModel extends DefaultTableModel {
public static final String[] HEADERS = { "One", "Two", "Three" };
public static final Vector<String> V_HEADERS = new Vector<>(Arrays.asList(HEADERS));
public MyModel(Vector<Vector<Object>> data) {
super(data, V_HEADERS);
}
public MyModel() {
super(HEADERS, 0);
}
}