I'm quite sure this problem has a simple solution, but I haven't been able to solve it.
Scenario:
1) I have a JTable linked to a model based on a LinkedHashMap with (for example) 10 elements.
2) External events delete the first 2 elements almost at the same time, so:
2.1) The model deletes element #0, and throws an event like "row linked to element #0, it is, row #0, has changed".
2.2) Before the JTable has time to be modified, the second element is deleted on the model and the event launched is the same, because the second element is now the first one.
3) The JTable processes both events "row #0 has been deleted".
I think this is why I am getting a "NULL error" like the following one:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at paneles.panel_positions.Elements_Manager.getValueAt(Elements_Manager.java:388)
at paneles.panel_positions.Elements_Manager$1Dates_Renderer.getTableCellRendererComponent(Positions_Manager.java:891)
at javax.swing.JTable.prepareRenderer(JTable.java:5736)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:778)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JViewport.paint(JViewport.java:731)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5230)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
at javax.swing.JComponent._paintImmediately(JComponent.java:5178)
at javax.swing.JComponent.paintImmediately(JComponent.java:4989)
at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
I've been thinking on any kind of synchronized mechanism so the second deletion can't be executed until the first one had been finished and executed the event on the JTable, but I can't figure it out which would be the correct way of doing this.
This is happening on a real time-events-processing app, so forcing the events source to wait in this way doesn't seem to be a good solution, but I can't figure it out a correct way of doing it. Any idea?
Thanks in advance.
EDIT:
Method on another thread that launches deletions:
public void delete_all_elements() {
cloned_model = mainobject.getCloned_model();
for (Element pos_aux : cloned_model.values()) {
notify_pos_to_be_deleted(pos_aux);
}
}
Code executed on the thread wich receives the previous message on a messages-queue:
...
model.rmv(row_index);
TableModelEvent event = new TableModelEvent (this, row_index, total_rows-1, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);
notify_suscriptors(event);
...
Code of notify_suscriptors:
...
((TableModelListener)listeners.get(i)).tableChanged(event);
...