有一个类保存了另一个类的DefaultTableModel。
file_path = new File( "c://Database//Directory//" );
file_table_stock_save = new File( file_path , "stockfile.file" );
file_path.mkdirs();
try
{
file_path..createNewFile();
fileoutputstream = new FileOutputStream( file_table_stock_save );
objectoutputstream = new ObjectOutputStream( fileoutputstream );
objectoutputstream.writeObject( stock.defaulttablemodel );
objectoutputstream.close();
fileoutputstream.close();
}
catch( Exception exception )
{.....}下面是读取DefaultTableModel的方式
file = new File( "C://Database//Directory//" , "stockfile.file" );
object = new Object();
if( file.exists() )
{
try
{
fileinputstream = new FileInputStream( file );
objectinputstream = new ObjectInputStream( fileinputstream );
object = objectinputstream.readObject();
objectinputstream.close();
fileinputstream.close();
}
catch( Exception exception )
{}
try
{
if( !( object == null ) )
defaulttablemodel = ( DefaultTableModel ) object;
}
catch( Exception exception )
{......}问题是文件始终存在,但有时文件无法读取。如何解决这个问题?类是否应该实现可序列化?JTable中的空单元格在读取时会导致错误吗?
发布于 2020-12-27 04:18:11
首先,我永远不会序列化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);
}
}https://stackoverflow.com/questions/65459946
复制相似问题