Exception occurs in ATrace2D.getNearestPointEuclid(...) because the size of the trace is modified between it.hasNext() and it.next().
while (it.hasNext()) {
point = it.next(); <-- here!!!
...
}
This happens because we access in the Chart2D.PointHighlighter.mouseMoved(..) callback use getNearestPoint without synchronising on anything.
@Override
public void mouseMoved(MouseEvent e) {
ITracePoint2D point = Chart2D.this.getPointFinder().getNearestPoint(e, Chart2D.this);
// don't work on empty charts:
if (point != null) {
ITracePoint2D previousHighlightedPoint = this.m_previousHighlighted.get(point.getListener());
if (!point.equals(previousHighlightedPoint)) {
ITrace2D trace = point.getListener();
// avoid duplicate or no highlighting in concurrent paint situation.
synchronized (Chart2D.this) {
synchronized (trace) {
this.clearOutdatedHighlighters(trace);
this.attachHighlighters(point);
this.m_previousHighlighted.put(trace, point);
Chart2D.this.setRequestedRepaint(true);
}
}
Chart2D.this.notifyPointHighlightListeners(point);
}
}
}
and no synchronisation is done deeper in the calls( getNearestPointManhattan and getNearestPointEuclid).
TODO: find where to lock the elements:
chart and trace should probably be lock as far down as possible, in getNearestPointEuclid.
The chart really need to be locked since the range of the chart could change...
and also to keep the synchronization order constant.
Full stack trace:
java.util.ConcurrentModificationException: null
at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source) ~[na:1.8.0_111]
at java.util.TreeMap$KeyIterator.next(Unknown Source) ~[na:1.8.0_111]
at info.monitorenter.gui.chart.traces.ATrace2D.getNearestPointEuclid(ATrace2D.java:1533) ~[jchart2d-code-0.0.1-rc.6.jar:na]
at info.monitorenter.gui.chart.Chart2D.getNearestPointEuclid(Chart2D.java:2196) ~[jchart2d-code-0.0.1-rc.6.jar:na]
at info.monitorenter.gui.chart.Chart2D$PointFinder$1.getNearestPoint(Chart2D.java:337) ~[jchart2d-code-0.0.1-rc.6.jar:na]
at info.monitorenter.gui.chart.Chart2D$PointFinder.getNearestPoint(Chart2D.java:369) ~[jchart2d-code-0.0.1-rc.6.jar:na]
at info.monitorenter.gui.chart.Chart2D$PointHighlighter.mouseMoved(Chart2D.java:468) ~[jchart2d-code-0.0.1-rc.6.jar:na]
at java.awt.AWTEventMulticaster.mouseMoved(Unknown Source) ~[na:1.8.0_111]
at java.awt.Component.processMouseMotionEvent(Unknown Source) ~[na:1.8.0_111]
at javax.swing.JComponent.processMouseMotionEvent(Unknown Source) ~[na:1.8.0_111]
Exception occurs in ATrace2D.getNearestPointEuclid(...) because the size of the trace is modified between it.hasNext() and it.next().
This happens because we access in the Chart2D.PointHighlighter.mouseMoved(..) callback use getNearestPoint without synchronising on anything.
and no synchronisation is done deeper in the calls( getNearestPointManhattan and getNearestPointEuclid).
TODO: find where to lock the elements:
chart and trace should probably be lock as far down as possible, in getNearestPointEuclid.
The chart really need to be locked since the range of the chart could change...
and also to keep the synchronization order constant.
Full stack trace: