JFreechart and thread safety

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
arwelbath
Posts: 24
Joined: Fri Aug 10, 2007 12:37 pm

JFreechart and thread safety

Post by arwelbath » Fri Mar 07, 2008 4:15 pm

Hi,
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)....

etc..

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

skunk
Posts: 1087
Joined: Thu Jun 02, 2005 10:14 pm
Location: Brisbane, Australia

Post by skunk » Fri Mar 07, 2008 4:58 pm

Like every other swing component, JFreeChart is not thread safe. You need to ensure that any operation that could result in a repaint of the chart (like updating the dataset, for example) only runs on the event dispatching thread.

Code: Select all

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        // update the datset
    }
});

skunk
Posts: 1087
Joined: Thu Jun 02, 2005 10:14 pm
Location: Brisbane, Australia

Post by skunk » Sat Mar 08, 2008 2:53 pm

Actually, on rereading the initial post, it appears that your problem is not related to updating the dataset from multiple threads since ChangeEvents from JSliders etc. should be processed on the EDT.

You could subclass the ChartPanel and override this method

Code: Select all

public void chartProgress(ChartProgressEvent event)
This event will notify you when painting is started and completed. Any attempts to update the dataset while the chart is painting could be discarded and/or queued.

Locked