A NullPointerException is thrown when trying to serialize a TableModel object while the associated JTable object is visible in a JFrame. I created a minimal, reproducible Example and will also include the Stack-Trace.
This is the NullPointerException reason:
Cannot invoke "javax.swing.CellRendererPane.paintComponent(java.awt.Graphics, java.awt.Component, java.awt.Container, int, int, int, int, boolean)" because "this.rendererPane" is null
I hope someone can help. Maybe the stack trace below helps to understand it better.
I am using AdoptOpenJDK14 (14.0.2.12-hotspot)
Here is the minimal, reproducible Example:
Serialization.java (Entrypoint of the Program)
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.table.AbstractTableModel;
import com.formdev.flatlaf.FlatDarkLaf;
public class Serialization {
enum SERIALIZATION_THREAD {
MAIN,
THREAD,
EDT
}
public static void main(String[] args) throws Exception {
// Create GUI with frame and model
UI ui = new UI();
// Serialize the table model
System.out.println("SERIALIZING ON MAIN THREAD");
sleep(1000);
serialize(ui.model, SERIALIZATION_THREAD.MAIN); // DOESN'T WORK
System.out.println("SERIALIZING ON SEPARATE THREAD");
sleep(1000);
serialize(ui.model, SERIALIZATION_THREAD.THREAD); // DOESN'T WORK
System.out.println("SERIALIZING ON EDT");
sleep(1000);
serialize(ui.model, SERIALIZATION_THREAD.EDT); // WORKS
}
public static void serialize(Serializable object, SERIALIZATION_THREAD thread) {
switch (thread) {
case MAIN:
serialize0(object);
break;
case THREAD:
new Thread(() -> serialize0(object)).start();
break;
case EDT:
SwingUtilities.invokeLater(() -> serialize0(object));
break;
default:
break;
}
}
public static void serialize0(Serializable object) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("some.dat"))) {
oos.writeObject(object);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void sleep(int ms){
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class UI {
JFrame frame;
MyAbstractModel model;
public UI() throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(() -> {
FlatDarkLaf.setup(); // When using FlatLaf, it causes a NullPointer when serializing.
model = new MyAbstractModel();
frame = new JFrame();
frame.add(new JTable(model));
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
System.out.println("Done Building GUI");
});
}
}
class MyAbstractModel extends AbstractTableModel {
private List<String> list = new ArrayList<>();
public MyAbstractModel() {
list = Collections.synchronizedList(new ArrayList<>());
list.add("A");
list.add("B");
list.add("C");
}
@Override
public int getRowCount() {
return list.size();
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return rowIndex + "-" + columnIndex;
}
@Override
public String getColumnName(int column) {
return "Column " + column;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
// TODO
}
}
This is the Stacktrace I got.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "javax.swing.CellRendererPane.paintComponent(java.awt.Graphics, java.awt.Component, java.awt.Container, int, int, int, int, boolean)" because "this.rendererPane" is null at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2191) at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2092) at java.desktop/javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1888) at com.formdev.flatlaf.ui.FlatTableUI.paint(FlatTableUI.java:397) at java.desktop/javax.swing.plaf.ComponentUI.update(ComponentUI.java:161) at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:797) at java.desktop/javax.swing.JComponent.paint(JComponent.java:1074) at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5255) at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1643) at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1618) at java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1556) at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1323) at java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5203) at java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5013) at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:865) at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:848) at java.base/java.security.AccessController.doPrivileged(AccessController.java:391) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:848) at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:823) at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:772) at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1884) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) at java.base/java.security.AccessController.doPrivileged(AccessController.java:391) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "javax.swing.JTable.getColumnModel()" because "this.table" is null at java.desktop/javax.swing.plaf.basic.BasicTableUI.getPreferredSize(BasicTableUI.java:1768) at java.desktop/javax.swing.JComponent.getPreferredSize(JComponent.java:1680) at java.desktop/javax.swing.JTable.setWidthsFromPreferredWidths(JTable.java:3205) at java.desktop/javax.swing.JTable.doLayout(JTable.java:3117) at java.desktop/java.awt.Container.validateTree(Container.java:1722) at java.desktop/java.awt.Container.validateTree(Container.java:1731) at java.desktop/java.awt.Container.validateTree(Container.java:1731) at java.desktop/java.awt.Container.validateTree(Container.java:1731) at java.desktop/java.awt.Container.validate(Container.java:1657) at java.desktop/javax.swing.RepaintManager$3.run(RepaintManager.java:745) at java.desktop/javax.swing.RepaintManager$3.run(RepaintManager.java:743) at java.base/java.security.AccessController.doPrivileged(AccessController.java:391) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:742) at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1883) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) at java.base/java.security.AccessController.doPrivileged(AccessController.java:391) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) Done