如何使用多个类的序列化实现备份和还原?

我试图序列化我存储在JTable中的对象(名称和注释)。 我希望能够将此信息保存到文件中,当我加载程序时,信息应该加载到JTable中。 当我单击备份按钮时,正在创建一个文件,但没有存储数据。 有人可以指导我正确的方向,告诉我我做错了什么? 我的代码如下:

import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import javax.swing.JFrame; import java.awt.CardLayout; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class tableTest { private JFrame frame; private JTable table; private JTextField notesTextField; private JTextField nameTextField; private List l; public tableTest() { new Serial().serialize(l); initialize(); } private void initialize() { frame = new JFrame(); frame.setBounds(0, 0, 1080, 900); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.getContentPane().setLayout(new CardLayout(0, 0)); final JTabbedPane tabbedPane1 = new JTabbedPane(JTabbedPane.TOP); tabbedPane1.setBackground(new Color(189, 183, 107)); frame.getContentPane().add(tabbedPane1, BorderLayout.CENTER); final JPanel Panel = new JPanel(); tabbedPane1.addTab("Table", null, Panel, null); Panel.setLayout(null); final JPanel Add = new JPanel(); tabbedPane1.addTab("Add to table", null, Add, null); Add.setLayout(null); nameTextField = new JTextField(); nameTextField.setBounds(428, 211, 308, 34); Add.add(nameTextField); nameTextField.setColumns(10); notesTextField = new JTextField(); notesTextField.setColumns(10); notesTextField.setBounds(428, 270, 308, 34); Add.add(notesTextField); JButton btnAddToTable = new JButton("Add to table"); btnAddToTable.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { DefaultTableModel dtm =(DefaultTableModel)table.getModel(); dtm.addRow(new Object[] { nameTextField.getText(), notesTextField.getText() }); } }); btnAddToTable.setBounds(472, 375, 103, 23); Add.add(btnAddToTable); JButton btnBackup = new JButton("Backup"); btnBackup.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new Serial().deSerialize(); } }); btnBackup.setBounds(613, 375, 103, 23); Add.add(btnBackup); JScrollPane scrollPane = new JScrollPane(); scrollPane.setBounds(10, 11, 1039, 733); Panel.add(scrollPane); table = new JTable(); scrollPane.setViewportView(table); table.setModel(new DefaultTableModel( new String[] { "Names", "Notes" }, 0)); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { tableTest window = new tableTest(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } } import java.io.Serializable; import java.util.ArrayList; public class List implements Serializable { private static final long serialVersionUID = 1L; private ArrayList pList; public List(){ pList = new ArrayList(); } public void addPerson(Person p) { pList.add(p); } public ArrayList getpList() { return pList; } public void setpList(ArrayList pList) { this.pList = pList; } } import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Serial { private List l; public void serialize(List l) { try (FileOutputStream fileOut = new FileOutputStream("address.ser")) { ObjectOutputStream os = new ObjectOutputStream(fileOut); os.writeObject(l); os.close(); } catch (Exception ex) { ex.printStackTrace(); } } public List deSerialize() { try (FileInputStream fileIn = new FileInputStream("address.ser")) { ObjectInputStream os = new ObjectInputStream(fileIn); List l; l = (List) os.readObject(); os.close(); } catch (Exception ex) { ex.printStackTrace(); } return l; } } import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 1L; private String pName; public Person(String pName){ setpName(pName); } public String getpName() { return pName; } public void setpName(String pName) { this.pName = pName; } } 

你似乎在倒退。 即

  • 备份时,应序列化反序列化
  • 恢复时应该反其道而行之。
  • 并且您似乎通过在备份按钮的ActionListener中调用反序列化并在类创建代码中序列化来完全向后执行此操作。
  • 编辑:此外,您正在序列化自定义类型列表的对象,但从不将表格模型中的数据添加到列表中。 所以List永远不会保存相关数据,所以你的序列化将是徒劳的。 而是序列化DefaultTableModel,或者在序列化之前将模型的数据传输到List对象。

另外,不相关但我觉得重要的建议:

  • 您应该首先在非常简单的程序中测试复杂的新概念,一个没有GUI,一个没有所有这些无关和不必要的复杂性。 因此,首先要删除GUI并使序列化和反序列化工作,然后使用GUI将其合并到更大更复杂的程序中。
  • 你不应该使用null布局并在组件上调用setBounds(...)来放置它们的绝对定位,因为这会使GUI非常不灵活,虽然它们在一个平台上看起来很好但在大多数其他平台或屏幕分辨率上看起来很糟糕这些都很难更新和维护。 相反,您将需要学习和学习布局管理器,然后嵌套JPanels,每个JPanels都使用自己的布局管理器来创建令人满意的复杂GUI,这些GUI在所有操作系统上都很好看。
  • 您将需要重命名自定义List类,以使其名称与重要的java.util.List类不冲突。

编辑
你在评论中提问:

所以一旦数据输入JTable,它应该在序列化之前转移到列表对象? 我该怎么做呢?

我要做的就是完全摆脱List类,我将Table的模型传递给我的serialize方法,我会在我的DefaultTableModel对象上调用getDataVector()来提取它的核,我会序列化它。

在反序列化时,我会做相反的事情 – 从磁盘中读取Vector并从中创建一个新的DefaultTableModel对象,从Vector中保存表的列标题。 至于代码细节,那就是你要解决的问题。