如何将 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 保存到文件中?的主要内容,如果未能解决你的问题,请参考以下文章