Search code examples
javaswingtimehistogramjfreechart

Why can't I copy a value from one XYSeriesCollection to other?


I'm using JFreeChart to create an image histogram in java swing. In order to create it I iterate over all pixels to get all the colors. Depending on the size and bit depth it takes some time.

Once I have all the data I put it into a XYSeriesCollection variable. To be able to show and hide some series latter I save a copy of that variable.

My problem is that if I do it like this:

final XYSeriesCollection data = createHistogram();
final XYSeriesCollection dataCopy = createHistogram();

It works without any problem, but it is not efficient, as I have to iterate over all pixels and that takes a while.

If I just copy it like this:

final XYSeriesCollection data = createHistogram();
final XYSeriesCollection dataCopy = data;

When I execute the code I get this exception:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Series index out of bounds
at org.jfree.data.xy.XYSeriesCollection.getSeries(XYSeriesCollection.java:263)

I think that this is because when I delete the series from data some how they also get deleted from dataCopy but shouldn't those be completely different? I just work with this methods:

data.removeAllseries();
data.addSeries(dataCopy.getSeries(index));

For example if I create:

int x = 5;
int y = x;
x=0;
System.out.println(y)

The output should still be 5 and it doesn't matter what I did with x. What am I doing or assuming that is wrong?

Thank you.


Solution

  • Note the difference between shallow versus deep copy. Your example, dataCopy = data, makes a shallow copy. Use the dataset's clone() method to make a deep copy:

    XYSeriesCollection dataCopy = (XYSeriesCollection) data.clone();
    

    You can see how clone() is implemented here. The fragment below creates a series, clones it, and updates the original to illustrate the effect.

    Code:

    XYSeriesCollection data = new XYSeriesCollection();
    XYSeries series = new XYSeries("Test");
    data.addSeries(series);
    series.add(1, 42);
    System.out.println(data.getSeries(0).getY(0));
    XYSeriesCollection dataCopy = (XYSeriesCollection) data.clone();
    series.updateByIndex(0, 21.0);
    System.out.println(data.getSeries(0).getY(0));
    System.out.println(dataCopy.getSeries(0).getY(0));
    

    Console:

    42.0
    21.0
    42.0
    

    Also consider the approach shown here, which may be faster.