如何将 AbstractTableModel 保存到文件中?

Posted

技术标签:

【中文标题】如何将 AbstractTableModel 保存到文件中?【英文标题】:How to save an AbstractTableModel into a file? 【发布时间】:2015-11-07 13:21:47 【问题描述】:

我正在尝试将已编辑的行从 JTable(类型 AbstractTableModel)保存 到文件中。我不知道该怎么做;或者可能使用 ObjectOutput 和 InputStream。

此外,我想在保存时从另一个 JTable 加载它。

为了给你一个更好的画面,我正在做一个 EPOS 系统,用户可以在其中编辑行数据(数量),当程序执行时,发现数量不为零,它会保存整行(使用当前详细信息)到文件中。这是为了让用户拥有已下订单的记录(用于 EPOS 和库存中的销售功能)。

当用户点击确认按钮时,保存部分有望被触发。

有人可以帮帮我吗?谢谢

【问题讨论】:

我不建议为此(或几乎任何东西)使用对象流。一种简单直接的方法是将它们保存为简单的 CSV 行。 你能告诉我怎么做吗 我引导你到Basic I/O Tutorial。 CSV 文件是所有字符串数据的最简单方法,因为该文件将包含字符串数据。但是如果你有其他数据类型(Integer、Date...),那么读取文件的过程会变得更加复杂,因为你需要将 String 转换为适当的数据类型。 我的想法是这样做,但有些事情没有加起来:创建一个包含 for 循环的方法。在这个 for 循环中,我有 if(model.getValueAt(i,4) != 0) add row details to orderList 将列表保存到文件中(通过从类订单调用方法保存)。我的问题是如何将 getvalueat(i,4) 转换为 int,因为 0(或其他)。以及如何将行详细信息添加到列表 orderList。第三个问题如何将列表保存在文件中。 【参考方案1】:

如果您阅读JTable API,您会发现它建议您使用XMLEncoder 进行长期存储。

我正在尝试从 JTable(类型 AbstractTableModel)中保存已编辑的行

您没有使用 AbstractTableModel。 AbstractTableModel 不提供任何数据存储。您正在使用扩展 AbstractTableModel 的 TableModel。假设您使用的是DefaultTableModel,这是一个允许您使用 XMLEncoder 和 XMLDecoder 的示例:

//  Following code is a more complete version of:
//  http://***.com/q/26250939/131872

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.*;

public class DefaultTableModelPersistenceDelegateTest

    private File file = new File("TableModel.xml");
    private final JTextArea textArea = new JTextArea();

    private final String[] columnNames = "Column1", "Column2";

    private final Object[][] data =
    
        "aaa", new Integer(1),
        "bbb\u2600", new Integer(2)
    ;

    private DefaultTableModel model = new DefaultTableModel(data, columnNames);
    private final JTable table = new JTable(model);

    public JComponent makeUI()
    
        model.setColumnCount(5);
        JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        sp.setResizeWeight(.3);
        sp.setTopComponent(new JScrollPane(table));
        sp.setBottomComponent(new JScrollPane(textArea));

        JPanel p = new JPanel();
        p.add(new JButton(new AbstractAction("XMLEncoder")
        
            @Override
            public void actionPerformed(ActionEvent e)
            
                try
                
                    OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
                    XMLEncoder xe = new XMLEncoder(os);
                    xe.setPersistenceDelegate(DefaultTableModel.class, new DefaultTableModelPersistenceDelegate());
                    xe.writeObject(model);
                    xe.close();

                    Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
                    textArea.read(r, null);
                
                catch (IOException ex)
                
                    ex.printStackTrace();
                
            
        ));

        p.add(new JButton(new AbstractAction("XMLDecoder")
        
            @Override
            public void actionPerformed(ActionEvent e)
            
                try
                
                    InputStream is = new BufferedInputStream( new FileInputStream( file ));
                    XMLDecoder xd = new XMLDecoder(is);
                    model = (DefaultTableModel)xd.readObject();
                    table.setModel(model);
                
                catch (IOException ex)
                
                    ex.printStackTrace();
                
            
        ));

        p.add(new JButton(new AbstractAction("clear")
        
            @Override
            public void actionPerformed(ActionEvent e)
            
                model = new DefaultTableModel();
                table.setModel(model);
            
        ));

        JPanel pnl = new JPanel(new BorderLayout());
        pnl.add(sp);
        pnl.add(p, BorderLayout.SOUTH);
        return pnl;
    

    public static void main(String[] args)
    
        EventQueue.invokeLater(new Runnable()
        
            @Override public void run()
            
                createAndShowGUI();
            
        );
    

    public static void createAndShowGUI()
    
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new DefaultTableModelPersistenceDelegateTest().makeUI());
        f.setSize(420, 340);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    


//  See following link for more information on Using XMLEncoder:
//  http://www.oracle.com/technetwork/java/persistence4-140124.html

class DefaultTableModelPersistenceDelegate extends DefaultPersistenceDelegate

    //  Initially creates an empty DefaultTableModel. The columns are created
    //  and finally each row of data is added to the model.

    @Override
    protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder encoder)
    
        DefaultTableModel model= (DefaultTableModel)oldInstance;

        //  Create XML to restore the column names

        Vector<String> columnNames = new Vector<String>(model.getColumnCount());

        for (int i = 0; i < model.getColumnCount(); i++)
        
            columnNames.add( model.getColumnName(i) );
        

        Object[] columnNamesData = new Object[]  columnNames ;
        encoder.writeStatement(new Statement(oldInstance, "setColumnIdentifiers", columnNamesData));

        //  Create XML to restore row data

        Vector row = model.getDataVector();

        for (int i = 0; i < model.getRowCount(); i++)
        
            Object[] rowData = new Object[]  row.get(i) ;
            encoder.writeStatement(new Statement(oldInstance, "addRow", rowData));
        
    


class DefaultTableModelPersistenceDelegate2 extends DefaultPersistenceDelegate

    //  Initially creates a DefaultTableModel with rows and columns. Then the
    //  columns are reset and proper names are used. Finally data is set for each
    //  cell in the model.

    @Override
    protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder encoder)
    
        super.initialize(type, oldInstance, newInstance, encoder);

        DefaultTableModel model= (DefaultTableModel)oldInstance;

        //  Create XML to restore the column names

        Vector<String> columnNames = new Vector<String>(model.getColumnCount());

        for (int i = 0; i < model.getColumnCount(); i++)
        
            columnNames.add( model.getColumnName(i) );
        

        Object[] columnNamesData = new Object[]  columnNames ;
        encoder.writeStatement(new Statement(oldInstance, "setColumnIdentifiers", columnNamesData));

        //  Create XML to reset the value of every cell to its value

        for (int row = 0; row < model.getRowCount(); row++)
        
            for (int col = 0; col < model.getColumnCount(); col++)
            
                Object[] o = new Object[] model.getValueAt(row, col), row, col;
                encoder.writeStatement(new Statement(oldInstance, "setValueAt", o));
            
        
    

如果您不使用 DefaultTableModel,则需要创建自己的 PersistenceDelegate。

【讨论】:

以上是关于如何将 AbstractTableModel 保存到文件中?的主要内容,如果未能解决你的问题,请参考以下文章

swing_AbstractTableModel 创建表格

QTableView中单元格内容居中对齐

禁用JTable中的用户编辑

急!!!!java 如何使jlabel单元格中数据不能被修改

根据数据类型,具有不同类型单元格的 Jtable

如何将Bitmap保存为本地图片文件?