Why do JTables make TableModels non serializable when rendered?

五迷三道 提交于 2019-12-06 14:07:01

JTable, a TableModelListener to it's own TableModel, is Serializable. Your custom TableModel is Serializable. Adding an additional TableModelListener that is also Serializable should make no difference, as shown below. Some suggestions:

  • Verify that the data structure contained in your TableModel is itself Serializable. To the extent that this represents a bug, it may be possible to serialize just the model's internal data structure. For example,

    System.out.println(copyObject(data));
    
  • Critically examine you choice to use serialization in this context; see also Effective Java: Chapter 11. Serialization.

Addendum: I updated the example to instantiate JTable, clone the table using serialization, update the copy and display both.

Screen:

Console:

New data

SSCCE:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

/* @see http://stackoverflow.com/a/19300995/230513 */
public class SerializationTest {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JTable table = new JTable(new BlankTableModel());
                JTable copy = copyObject(table);
                copy.setValueAt("New data", 0, 0);

                JFrame f = new JFrame("SerializationTest");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLayout(new GridLayout(0, 1, 5, 5));
                f.add(table, BorderLayout.NORTH);
                f.add(copy, BorderLayout.SOUTH);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });

    }

    private static class BlankTableModel extends AbstractTableModel implements Serializable {

        private static final long serialVersionUID = 3141592653589793L;
        private String data = "Test data";

        public BlankTableModel() {
            this.addTableModelListener(new InnerTableModelListener());
        }

        @Override
        public void setValueAt(Object o, int row, int col) {
            data = o.toString();
            this.fireTableCellUpdated(row, col);
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public int getRowCount() {
            return 2;
        }

        @Override
        public Object getValueAt(int row, int col) {
            return data;
        }

        private void save() {
            BlankTableModel model = copyObject(this);
            System.out.println(model.getValueAt(0, 0));
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            return true;
        }

        private class InnerTableModelListener implements TableModelListener, Serializable {

            private static final long serialVersionUID = 2718281828459045L;

            @Override
            public void tableChanged(TableModelEvent e) {
                save();
            }
        }
    }

    private static <T extends Serializable> T copyObject(final T source) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(source);
            ObjectInputStream ois = new ObjectInputStream(
                new ByteArrayInputStream(baos.toByteArray()));
            final T copy = (T) ois.readObject();
            return copy;
        } catch (Exception e) {
            throw new AssertionError("Error copying: " + source);
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!