Так недавно я работал над инструментом для нас здесь, чтобы настроить определенные приложения. Это не должно было быть чем-то действительно потрясающим, просто базовым инструментом с некоторым созданием сценариев SQL и созданием нескольких файлов XML. Во время этого я создал серию объектов JTable с собственной реализацией AbstractTableModel. После того, как я все построил, и дошел до того, что тестировал сохранение и загрузку, используя неудачную сериализацию AbstractTableModel (просто записанной на диск с использованием ObjectStreamWriter). Мне потребовался почти весь день, чтобы понять, что происходит. Когда я попытаюсь их сериализовать, я получаю NotSerializableException в java.lang.reflect.Constructor. Я не знал, что это такое, потому что моя модель таблицы содержала только сериализуемые сущности, и все слушатели, которые я подключил, также были сериализованы, а родительский класс также сериализуем. После многократного поиска и нескольких полезных сообщений отсюда я обнаружил, что при добавлении TableModelListener в реализацию AbstractTableModel добавляется еще один прослушиватель в дополнение к тому, который вы добавили, типа javax.swing.event.TableModelListener, который isn ' t serializable (см. http://docs.oracle.com/javase/7/docs/api/javax/swing/event/TableModelListener.html для интерфейса, я не знаю реализации). EDIT Модель не добавляет этот несериализуемый прослушиватель, JTable делает. Мой вопрос в основном, почему этот объект будет добавлять свой собственный несериализуемый объект изнутри, тем самым отрицая тот факт, что он действительно реализует Serializable? Это что-то, что я должен сообщить в качестве ошибки?Почему JTables делает TableModels не сериализуемыми при визуализации?
FYI Работаю я должен был просто удалить всех слушателей, сериализовать, а затем снова добавить слушателей. При десериализации я должен был только добавить тот, который я создал, и модель снова создала другую.
Редактировать Попробуйте сериализовать эту модель с классом сериализатора, вызванным вызовом метода 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());
}
здесь простой графический интерфейс
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);
}
}
Вы уверены в этом пункте? [Исходный код] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/javax/swing/table/AbstractTableModel.java#AbstractTableModel) не показывает это , а в [javadoc] (http://docs.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html) указано, что это 'Serializable'. Конечно, когда вы устанавливаете свою модель на 'JTable',' JTable' добавит слушателя (сама таблица) к модели, которая не является 'Serializable' – Robin
Да, я уверен. Попробуйте сами. Создайте простую форму с помощью JTable, создайте ее AbstractTableModel, а затем сериализуйте ее с помощью ObjectOutputStream. Теперь добавьте к нему слушателя (обратите внимание на количество слушателей в коллекции слушателей до и после) и попробуйте снова сериализовать его. Вы получите NotSerializableException –
звучит как-то неправильно с кодом, который вы не показываете – kleopatra