そのため、最近、特定のアプリケーションを構成するためのツールに取り組んでいました。SQL スクリプトを生成し、いくつかの XML ファイルを作成する基本的なツールで十分です。この間、AbstractTableModel の独自の実装で一連の JTable オブジェクトを作成しました。すべてを構築し、AbstractTableModel (ObjectStreamWriter を使用してディスクに書き込まれたばかり) を使用して保存と読み込みをテストしている時点で、シリアル化に失敗しました。何が起こっているのかを理解するのにほぼ一日かかりました。それらをシリアライズしようとすると、java.lang.reflect.Constructor で NotSerializableException が発生します。テーブル モデルにはシリアル化可能なエンティティしか含まれておらず、アタッチしたすべてのリスナーもシリアル化可能であったため、これが何なのかわかりませんでした。親クラスもシリアライズ可能です。多くの掘り下げと、ここからのいくつかの役立つ投稿の後、TableModelListener を AbstractTableModel 実装に追加すると、追加したものに加えて、タイプ javax.swing.event.TableModelListener の別のリスナーが追加されることがわかりました。 t シリアライズ可能 (参照インターフェイスについてはhttp://docs.oracle.com/javase/7/docs/api/javax/swing/event/TableModelListener.html、実装はわかりません)。編集モデルはこのシリアル化不可能なリスナーを追加しませんが、JTable は追加します。私の質問は本質的に、なぜこのオブジェクトが独自の非シリアル化可能オブジェクトを内部的に追加し、実際にシリアル化可能を実装しているという事実を否定するのでしょうか? これはバグとして報告する必要がありますか?
参考までに、私が行った回避策は、すべてのリスナーを単純に削除し、シリアル化してから、リスナーを再度追加することでした。逆シリアル化するときは、作成したものを追加するだけで済み、モデルは別のものを独自に作成しました。
編集 setValueAt() メソッドを呼び出して提供されるシリアライザ クラスを使用して、このモデルをシリアライズしてみてください。
import java.io.Serializable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
public class BlankTableModel extends AbstractTableModel implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6063143451207205385L;
public BlankTableModel()
{
this.addTableModelListener(new InnerTableModelListener());
}
@Override
public void setValueAt(Object o, int x, int y)
{
this.fireTableChanged(new TableModelEvent(this, x, y));
}
public int getColumnCount() {
// TODO Auto-generated method stub
return 2;
}
public int getRowCount() {
// TODO Auto-generated method stub
return 2;
}
public Object getValueAt(int arg0, int arg1) {
// TODO Auto-generated method stub
return "Test Data";
}
private void save()
{
Serializer.SerializeObject(this);
}
@Override
public boolean isCellEditable(int rowindex, int colindex)
{
return true;
}
private class InnerTableModelListener implements TableModelListener, Serializable
{
@Override
public void tableChanged(TableModelEvent arg0) {
save();
}
}
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Serializer {
public static void SerializeObject(Serializable object)
{
File out = new File("USE A VALID PATH");
if (!out.exists())
{
try {
out.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
}
else
{
out.delete();
try {
out.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try (FileOutputStream fos = new FileOutputStream(out);
ObjectOutputStream oos = new ObjectOutputStream(fos))
{
oos.writeObject(object);
}catch (Exception e)
{
e.printStackTrace();
}
}
}
次に、保存方法をこれに置き換えてみてください
private void save()
{
for (TableModelListener l : this.getTableModelListeners())
{
this.removeTableModelListener(l);
}
Serializer.SerializeObject(this);
this.addTableModelListener(new InnerTableModelListener());
}
ここに簡単なGUIがあります
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JTable;
public class MainForm extends JFrame {
public static void main(String[] args)
{
MainForm form = new MainForm();
form.show();
}
public MainForm()
{
this.setBounds(100, 100, 600, 600);
BlankTableModel model = new BlankTableModel();
JTable table = new JTable(model);
table.setPreferredSize(new Dimension(500,500));
this.getContentPane().add(table);
}
}