Como gravar um estado JTable com dados no arquivo xml usando XMLEndcoder em java

Eu quero salvar JTable no arquivo xml usando XMLEncoder . Quando estamos salvando em um arquivo, obtendo uma exceção:

 java.lang.InstantiationException: javax.swing.plaf.basic.BasicTableUI$Handler Continuing ... java.lang.Exception: XMLEncoder: discarding statement ColorPropertyTable.removeMouseMotionListener(BasicTableUI$Handler); Continuing ... 

http://java.sun.com/products/jfc/tsc/articles/persistence4/
http://www.oracle.com/technetwork/java/persistence4-140124.html
Registrando para Notificações de Exceções
Tanto o XMLEncoder quanto o XMLDecoder capturam exceções e normalmente conseguem recuperá-los, permitindo que as partes do archive não afetadas pela exceção sejam gravadas ou lidas . Você pode descobrir mais sobre quaisquer exceções levantadas nos processos de codificação e decodificação, registrando um ExceptionListener da seguinte maneira:

insira a descrição da imagem aqui

Exemplo

 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 final JTextArea textArea = new JTextArea(); private final String[] columnNames = {"A", "B"}; private final Object[][] data = { {"aaa", "ccccccc"}, {"bbb", "\u2600\u2601\u2602\u2603"} }; private DefaultTableModel model = new DefaultTableModel(data, columnNames); private final JTable table = new JTable(model); public JComponent makeUI() { JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT); sp.setResizeWeight(.5); 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 { File file = File.createTempFile("output", ".xml"); try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { XMLEncoder xe = new XMLEncoder(os); xe.setPersistenceDelegate( DefaultTableModel.class, new DefaultTableModelPersistenceDelegate()); // xe.setExceptionListener(new ExceptionListener() { // @Override public void exceptionThrown(Exception exception) { // //XXX: exception.printStackTrace(); // } // }); // xe.writeObject(table); xe.writeObject(model); //xe.flush(); xe.close(); } try (Reader r = new BufferedReader( new InputStreamReader(new FileInputStream(file), "UTF-8"))) { textArea.read(r, "temp"); } } catch (IOException ex) { ex.printStackTrace(); } } })); p.add(new JButton(new AbstractAction("XMLDecoder") { @Override public void actionPerformed(ActionEvent e) { try (InputStream is = new BufferedInputStream( new ByteArrayInputStream(textArea.getText().getBytes("UTF-8")))) { 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(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } } //http://web.archive.org/web/20090806075316/http://java.sun.com/products/jfc/tsc/articles/persistence4/ //http://www.oracle.com/technetwork/java/persistence4-140124.html class DefaultTableModelPersistenceDelegate extends DefaultPersistenceDelegate { @Override protected void initialize( Class type, Object oldInstance, Object newInstance, Encoder encoder) { super.initialize(type, oldInstance, newInstance, encoder); DefaultTableModel m = (DefaultTableModel) oldInstance; // Vector v = m.getDataVector(); // for (int i = 0; i < m.getRowCount(); i++) { // encoder.writeStatement( // new Statement(oldInstance, "addRow", new Object[] { (Vector) v.get(i) })); // } for (int row = 0; row < m.getRowCount(); row++) { for (int col = 0; col < m.getColumnCount(); col++) { Object[] o = new Object[] {m.getValueAt(row, col), row, col}; encoder.writeStatement(new Statement(oldInstance, "setValueAt", o)); } } } } 

Essa resposta é baseada no exemplo do aterai. É um pouco mais completo porque também persistirá os nomes das colunas:

 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 DefaultTableModelPersistenceDelegate2()); 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); } } //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; Vector columnNames = new Vector(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)); 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)); } } }