Problem with disposal of ChartComposite object

A free public discussion forum for the JFreeChart class library.

Problem with disposal of ChartComposite object

Postby paulb » Fri Apr 18, 2008 11:50 am

I had a problem with using JFreeChart in an RCP Application. However, it should apply for all uses with SWT.

I have several TimeSeries which are plotted in an XYStepChart using TimeSeriesCollection. Data is added to the TimeSeries on a regular basis. This is independent of whether the chart is visible or not.
The chart is displayed in an editor (RCP) using ChartComposite. So each time the editor is openened, a ChartComposite is created using the JFreeChart object.
The problem was that after closing and reopening the editor the chart would not be correctly updated with the TimeSeries data that was added while it was not visible and also not according to newly added data (again, data is added regularly, whether the chart is visible (i.e. as a composite) or not).
I figured out that the reason for this was in the disposal of the ChartComposite object (which is disposed when its parent is disposed, i.e., when the editor is closed). The ChartComposite is registered as a listener to the respective JFreeChart which is in turn a listener of the data sets. After disposing the ChartComposite the update of the TimeSeries caused an exception because of the notifications to the still registered ChartComposite object.
Interestingly, manually unregistering the ChartComposite from the JFreeChart object before disposal did not help. The reason was that - I don't know why - the ChartComposite appeared twice in the list of listeners in the JFreeChart object. So unregistering it twice was the solution.

I would consider this a bug (and especially I'm not sure if it is "guaranteed" that the ChartComposite is registered as a listener twice - or maybe more often in some cases) or am I doing anything wrong? Also, shouldn't the ChartComposite unregister itself as a listener when it is disposed (I'm not sure if that is possible, though..).

Thanks for the help.
-- Paul
paulb
 
Posts: 3
Joined: Fri Apr 18, 2008 11:44 am

Postby david.gilbert » Fri Apr 18, 2008 3:50 pm

Thanks for reporting this. I'm not all that familiar with the SWT code, but looking through the constructor I can see the cause of the ChartComposite being registered twice as a listener. It gets registered first in the call:

Code: Select all
this.setChart(jfreechart);


...then again later on in the constructor:

Code: Select all
        if (this.chart != null) {
            this.chart.addChangeListener(this);
            ...
        }


That's wrong, but I'll have to study the code some more to work out which one should be removed.

Regarding whether or not the ChartComposite should deregister itself when it is disposed - yes, I think it should (and ChartPanel probably suffers the same bug, I'll have a look at that too).

I opened this bug report to track it:

http://sourceforge.net/tracker/index.ph ... tid=115494
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Ask your company to buy the JFreeChart Developer Guide
:idea: Check out other products sold by my company Object Refinery Limited
david.gilbert
JFreeChart Project Leader
 
Posts: 11282
Joined: Fri Mar 14, 2003 10:29 am

Postby paulb » Sat Apr 19, 2008 11:46 am

Thanks for the quick reply. I didn't have the chance to take a closer look at the ChartComposite code, yesterday. Also I am not so familiar with the JFreeChart internals.
Thanks for now and I'll keep you updated if I find out more.
paulb
 
Posts: 3
Joined: Fri Apr 18, 2008 11:44 am

Postby paulb » Thu Apr 24, 2008 1:13 am

A temporary workaround for those who don't want to change the JFreeChart code is to register as a disposal listener of the ChartComposite object. Even though it's relatively obvious, some sample code:

Code: Select all
class ...  implements DisposeListener {
   ChartComposite chartComposite;
   JFreeChart chart;

   public ..  {
      //...
      chart = ...
      chartComposite = new ChartComposite(..., chart, ...);
      chartComposite.addDisposeListener(this);
   }
   
   public void widgetDisposed(DisposeEvent e) {      // called when chartComposite is disposed
      // dirty double removal of possible listener roles of chartComposite
      chart.removeChangeListener(chartComposite);
      chart.removeProgressListener(chartComposite);
      chart.removeChangeListener(chartComposite);
      chart.removeProgressListener(chartComposite);
   }

}
paulb
 
Posts: 3
Joined: Fri Apr 18, 2008 11:44 am

Postby heprom » Sat May 24, 2008 9:00 pm

Hi, this problem is now fixed in the svn tree. Will be in jfreechart 1.10.

Thanks for your feedback.
heprom
 
Posts: 91
Joined: Sat May 27, 2006 4:25 am
Location: Paris

Postby beckchr » Fri May 30, 2008 9:01 am

heprom wrote:Hi, this problem is now fixed in the svn tree. Will be in jfreechart 1.10.

Thanks for your feedback.


Hi, we should remove the block
if (this.chart != null) {
....
}
completely from the constructor, as the same code appears in setChart(), which is called anyway.
beckchr
 
Posts: 9
Joined: Wed Feb 28, 2007 2:57 pm


Return to JFreeChart - General

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 19 guests