I have a chart which gets updated periodically. Occasionally, these updates can happen very quickly (i.e. some values can be changed using a JSlider which can result in some very fast updates). When this happens, I periodically get the folowing...
Code: Select all
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 189, Size: 90
at java.util.ArrayList.RangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at org.jfree.data.xy.XYSeries.getDataItem(XYSeries.java:445)
at org.jfree.data.xy.XYSeriesCollection.getX(XYSeriesCollection.java:275)
at org.jfree.data.xy.AbstractXYDataset.getXValue(AbstractXYDataset.java:77)
at FastXYPlot.hasRendered(FastXYPlot.java:36)
at FastXYPlot.render(FastXYPlot.java:98)
at org.jfree.chart.plot.XYPlot.draw(XYPlot.java:2680)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1214)
at org.jfree.chart.ChartPanel.paintComponent(ChartPanel.java:1270)
at javax.swing.JComponent.paint(Unknown Source)....
Now, it's pretty clear to me that what's happening is that during these very fast updates, the code is trying to update the chart before the previous update has finished. Also, it looks like the updates are being queued, so the chart carries on updating for a couple of seconds after the slider has finished moving. So, I think what I need to do is to make the chart unavailable for update until the previous task has finished.
I'm new to Java, and am looking into this (I have O'Reilly's 'Learning Java' in front of me here as I type!), but am quite confused. Can someone help me with a very general example of what I need to do??
In general terms, my code has the following form...
Code: Select all
public class myChart{
public myChart(){};
public ChartPanel mkPointsAndLinesLinChart(XYSeriesCollection pointsColl){
.... this make the chart based on the input collection, and returns it in a panel.......
return panel;
}
public updateChart(float data[][], XYSeriesCollection coll, int points) {
XYSeries thisSeries = coll.getSeries(contrast);
thisSeries.clear();
for (int i=0 ; i<points-1 ; i++) {
thisSeries.add(data[i][0],data[i][1],false);
};
thisSeries.add(data[points][0],data[points][1]);
}
}
So, I've been looking in my Java book and this seems to be a case of thread safety. Somehow, I need to lock the updateChart method so that it can't be called before the chart is finished (using 'synchronized'?). Also for my app, it would make more sense for any 'rejected' calls to the update method (i.e. calls that are made before the chart is ready) are simply igmored and disposed of rather than put in a queue.
Could anyone provide a general example as to how something like this might work?
Cheers,
arwel