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

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

问题描述

我正在尝试序列化我存储在 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;
}


}

推荐答案

你似乎在做事倒退.即,

You appear to be doing things backwards. i.e.,

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

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

Also, unrelated but I feel important advice:

  • 您应该首先在非常简单的程序中测试复杂的新概念,一个没有 GUI,一个没有所有这些无关和不必要的复杂性.因此,摆脱您的 GUI 并首先让您的序列化和反序列化工作,然后再将其合并到您的更大、更复杂的带有 GUI 的程序中.
  • 您不应该使用 null 布局并在您的组件上调用 setBounds(...) 以绝对定位放置它们,因为这会导致 GUI 非常不灵活,而它们在一个平台上可能看起来不错,但在大多数其他平台或屏幕分辨率上看起来很糟糕,并且很难更新和维护.相反,您需要研究和学习布局管理器,然后嵌套 JPanel,每个 JPanel 都使用自己的布局管理器来创建在所有操作系统上看起来都不错的令人愉悦且复杂的 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 类,我会将 Table 的模型传递到我的序列化方法中,我会在我的 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 保存表的列标题.至于代码细节,那你自己琢磨吧.

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天全站免登陆