Wrong calculation of java2d pos. after resizing ChartPanel

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
patb
Posts: 11
Joined: Sun Aug 03, 2008 7:55 pm

Wrong calculation of java2d pos. after resizing ChartPanel

Post by patb » Tue Apr 27, 2010 3:06 pm

Hello,

I have a problem with calculating the location (java2d Point) for a given value for a NumberAxis (or point of time for a DateAxis) just after resizing the ChartPanel. It is hard to explain, I try my best:

My code to calculate the position is the following:

Code: Select all

public Point getCoordinatesByChartLocation( double value, Calendar Time )
{
  double timeInMillis = time.getTimeInMillis();
  
  Rectangle2D plotArea = getChartRenderingInfo().getPlotInfo().getDataArea();
  XYPlot plot = (XYPlot) getChart().getPlot();
  
  RectangleEdge domainAxisEdge = plot.getDomainAxisEdge();
  RectangleEdge rangeAxisEdge = plot.getRangeAxisEdge();
  
  double x = plot.getDomainAxis().valueToJava2D( timeInMillis, plotArea, domainAxisEdge );
  double y = plot.getRangeAxis().valueToJava2D( value, plotArea, rangeAxisEdge );
  
  Point2D p2d = translateScreenToJava2D( new Point( (int)x, (int)y ) );
  
  return new Point( (int)p2d.getX(), (int)p2d.getY() );
}

This code works perfectly when no ChartPanel resizing is done (so the ChartPanel size is fix). Don't get me wrong: I am able to resize the ChartPanel and my calculation still works. But:

The result of the call to "getCoordinatesByChartLocation" is the value, that would have been calculated right before the call to "ChartPanel.setSize(...)", it does not reflect the actual ChartPanel size, but always the size of the ChartPanel before the "ChartPanel.setSize(...)".

The problem in code:

Code: Select all


// build the chartpanel with the plot, axes etc.
ChartPanel chartPanel = new ChartPanel(...);
chartPanel.setSize( 400, 300 );

Point point = getCoordinatesByChartLocation( 100, myTime_15_10 );

// Setting the test panel to the new location (see the following picture),
// the test panel sits exactly on the time 15:10. the testPanel is just a
// simple JPanel, sitting on top of the ChartPanel in the same container.
testPanel.setLocation( point );

// Now we resize the chart panel
chartPanel.setSize( 500, 300 );

// Calculate the new point with the same time
Point point = getCoordinatesByChartLocation( 100, myTime_15_10 );
testPanel.setLocation( point );


// Now the testPanel does NOT sit on the real 15:10 on the domain axis, it is
// on the old position, as if the chartPanel had the same old size of 400x300
// instead of 500x300 !
The really interesting thing is, that if I insert the following line right after the "chartPanel.setSize( 500, 300 );"

Code: Select all

Thread.sleep( 1000 );
delaying the calculation of the new testPanel position, the position is correct! So what is going on after the "chartPanel.setSize( 500, 300 );"?

To better illustrate the problem, please see the following picture:

Image

I looked for some kind up "update" method to tell the ChartPanel to recognize it's new size and update internal states or something. I don't know if this could solve the problem, or maybe my calculation code above is wrong?

I hope I could describe the problem well enough.


I really appreciate any help you can offer - thanks a lot!

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

Re: Wrong calculation of java2d pos. after resizing ChartPanel

Post by skunk » Tue Apr 27, 2010 7:52 pm

All repainting in Swing occurs asynchronously. You need to install a listener using this method

Code: Select all

public void addProgressListener(ChartProgressListener listener)
and wait until you receive a DRAWING_FINISHED notification before doing the calculation.

patb
Posts: 11
Joined: Sun Aug 03, 2008 7:55 pm

Re: Wrong calculation of java2d pos. after resizing ChartPanel

Post by patb » Tue Apr 27, 2010 11:02 pm

Hello skunk,
skunk wrote:All repainting in Swing occurs asynchronously. You need to install a listener using this method

Code: Select all

public void addProgressListener(ChartProgressListener listener)
and wait until you receive a DRAWING_FINISHED notification before doing the calculation.
a big question and such a small answer ;) But there is nothing more to say, you are absolutely right, using a ChartProgressListener I could solve the problem.

Thanks a lot for your help!

Just a little side-question: Is Swing painting in the Event Dispatch Thread, or in another painting-thread parallel to the EDT?

Locked