如何使用多个类的序列化实现备份和还原? [英] How do I implement backup and restore using serialisation with multiple classes?

查看:151
本文介绍了如何使用多个类的序列化实现备份和还原?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im trying to serialise objects(Names and notes) which I store in my JTable. I want to be able to save this information to a file and when I load the program, the information should load into the JTable. When I click the backup button a file is being created, but there is no data being stored. Could someone please guide me in the right direction and inform me what im doing wrong? My code is as follows:

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;
}


}


推荐答案

你似乎在倒退。即,


  • 备份时,序列化 反序列化 序列化

  • 恢复时应该反其道而行之。

  • 您似乎通过在备份按钮的ActionListener中调用deserialize并在类创建代码中序列化来完全向后执行此操作。

  • 编辑:此外,您正在序列化自定义类型List的对象,但从不将表格模型中的数据添加到List。所以List永远不会保存相关数据,所以你的序列化将是徒劳的。而是序列化DefaultTableModel,或者在序列化之前将模型的数据传输到List对象。

  • You should serialize not de-serialize when you back up.
  • You should do the opposite when you restore.
  • And you appear to be doing this completely backwards by calling deserialize in your backup button's ActionListener and serialize in your class creation code.
  • Also, you're serializing an object of custom type List but are never adding data from your table's model to List. So List will never hold relevant data, and so your serialization will be futile. Instead either serialize the DefaultTableModel, or transfer the model's data to the List object before serializing it.

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

Also, unrelated but I feel important advice:


  • 您应该首先在非常简单的程序中测试复杂的新概念,一个没有GUI,一个没有所有这些无关和不必要的复杂性。因此,摆脱您的GUI并使序列化和反序列化工作首先,然后只使用GUI将其合并到更大更复杂的程序中。

  • 你不应该使用 null 布局并在组件上调用 setBounds(...)来将它们置于绝对位置这使得非常不灵活的GUI虽然在一个平台上看起来很好看,但在大多数其他平台或屏幕分辨率上看起来很糟糕,并且很难更新和维护。相反,你会想要学习和学习布局管理器,然后嵌套JPanels,每个都使用自己的布局管理器来创建令人愉悦的复杂GUI,在所有操作系统上看起来都很好。

  • 你会想要重命名自定义List类,使其名称与重要的 java.util.List 类不冲突。

  • You should test complex new concepts in very simple program at first, one without a GUI, one without all this unrelated and unnecessary complexity. So get rid of your GUI and get your serialization and deserializaation working first, and only then incorporate it into your greater and more complex program with the GUI.
  • You should not use a null layout and calling setBounds(...) on your components to place them with absolute positioning as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain. Instead you will want to study and learn the layout managers and then nest JPanels, each using its own layout manager to create pleasing and complex GUI's that look good on all OS's.
  • You will want to rename your custom List class so that it's name doesn't conflict with the important java.util.List class.

编辑

你请注释:

Edit
You ask in comment:


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

So once the data has been entered into the JTable, it should be transfered to the list object before serialization? How would I go about doing this?

我会做的就是完全摆脱List类,我会通过将表格模型放入我的序列化方法中,我会在我的DefaultTableModel对象上调用 getDataVector()来提取其核心,我会将其序列化。

What I would do would be to get rid of the List class entirely, I would pass the Table's model into my serialize method, I would call getDataVector() on my DefaultTableModel object to extract its nucleus, and I would serialize that.

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

When de-serializing, I'd do the opposite -- read in the Vector from the disk and create a new DefaultTableModel object from it, from a Vector<String> that holds the table's column headings. As for the code details, well that's for you to work out.

这篇关于如何使用多个类的序列化实现备份和还原?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆