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

时间:2014-04-23 02:50:35

标签: java swing object serialization arraylist

我试图序列化我存储在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<Person> pList;

public List(){

    pList = new ArrayList<Person>();
}

public void addPerson(Person p) {
    pList.add(p);

}

public ArrayList<Person> getpList() {
    return pList;
}

public void setpList(ArrayList<Person> 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;
}


}

1 个答案:

答案 0 :(得分:2)

你似乎在倒退。即,

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

此外,无关,但我觉得重要的建议:

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

修改
你在评论中提问:

  

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

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

当反序列化时,我做相反的事情 - 从磁盘中读取Vector并从保存表格列的Vector<String>中创建一个新的DefaultTableModel对象标题。至于代码细节,那么你可以解决这个问题。