Clone() Not Supported

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
converge
Posts: 30
Joined: Wed Jun 16, 2004 3:00 pm

Clone() Not Supported

Post by converge » Fri Aug 15, 2014 8:07 pm

I have been using the clone function with success until I updated to version 1.0.19. Now I get a CloneNotSupportedException. Here is my code:

Code: Select all

JFreeChart exportChart = null;
try {
    exportChart = (JFreeChart) getChart().clone();
} catch (CloneNotSupportedException e) {
    logger.log(Level.SEVERE, null, e);
}

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Clone() Not Supported

Post by david.gilbert » Sat Aug 16, 2014 5:28 am

Can you post the full stack trace? Even better would be a small, self-contained demo program that reproduces the issue.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

converge
Posts: 30
Joined: Wed Jun 16, 2004 3:00 pm

Re: Clone() Not Supported

Post by converge » Mon Aug 18, 2014 1:35 pm

Here is the stack trace. I'll try to get the code into a self-contained program.

Code: Select all

Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: java.lang.CloneNotSupportedException: Failed to clone.
	at org.jfree.chart.util.CloneUtils.cloneMapValues(CloneUtils.java:100)
	at org.jfree.chart.renderer.xy.AbstractXYItemRenderer.clone(AbstractXYItemRenderer.java:1505)
	at org.jfree.chart.renderer.xy.XYLineAndShapeRenderer.clone(XYLineAndShapeRenderer.java:1267)
	at org.jfree.util.ObjectUtilities.clone(ObjectUtilities.java:170)
	at org.jfree.chart.util.CloneUtils.cloneMapValues(CloneUtils.java:98)
	at org.jfree.chart.plot.XYPlot.clone(XYPlot.java:5570)
	at org.jfree.util.ObjectUtilities.clone(ObjectUtilities.java:170)
	at org.jfree.util.ObjectUtilities.deepClone(ObjectUtilities.java:219)
	at org.jfree.chart.plot.CombinedDomainXYPlot.clone(CombinedDomainXYPlot.java:777)
	at org.jfree.chart.JFreeChart.clone(JFreeChart.java:1721)
	at com.testapp.iijnew.graph.ui.ChartPanelX.createExportChart(ChartPanelX.java:109)
	at com.testapp.iijnew.graph.ui.ChartPanelX.doCopy(ChartPanelX.java:78)
	at com.testapp.iijnew.graph.ui.testappChartPanel.doCopy(testappChartPanel.java:142)
	at com.testapp.iijnew.graph.ui.DiffPattPanel$37.actionPerformed(DiffPattPanel.java:1114)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
	at java.awt.Component.processMouseEvent(Component.java:6527)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
	at java.awt.Component.processEvent(Component.java:6292)
	at java.awt.Container.processEvent(Container.java:2234)
	at java.awt.Component.dispatchEventImpl(Component.java:4883)
	at java.awt.Container.dispatchEventImpl(Container.java:2292)
	at java.awt.Component.dispatchEvent(Component.java:4705)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
	at java.awt.Container.dispatchEventImpl(Container.java:2278)
	at java.awt.Window.dispatchEventImpl(Window.java:2739)
	at java.awt.Component.dispatchEvent(Component.java:4705)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
	at java.awt.EventQueue.access$400(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:697)
	at java.awt.EventQueue$3.run(EventQueue.java:691)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.awt.EventQueue$4.run(EventQueue.java:719)
	at java.awt.EventQueue$4.run(EventQueue.java:717)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.CloneNotSupportedException: Failed to clone.
	at org.jfree.util.ObjectUtilities.clone(ObjectUtilities.java:190)
	at org.jfree.chart.util.CloneUtils.cloneMapValues(CloneUtils.java:98)
	... 51 more


converge
Posts: 30
Joined: Wed Jun 16, 2004 3:00 pm

Re: Clone() Not Supported

Post by converge » Mon Aug 18, 2014 7:16 pm

Clone fails in this self-contained code. There seems to be an issue with the XYToolTipGenerator.

Code: Select all

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.XYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;

public class CloneTest {

    public static void main(String args[]) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart("Title", "Label1", "Label2", createDataset(), false, true, false);
        XYPlot xyPlot = (XYPlot) chart.getPlot();
        xyPlot.getRenderer(0).setSeriesToolTipGenerator(0, new TestToolTipGenerator());

        JFreeChart exportChart = null;
        try {
            exportChart = (JFreeChart) chart.clone();
        } catch (CloneNotSupportedException e) {
        }
    }

    private static class TestToolTipGenerator implements XYToolTipGenerator {

        @Override
        public String generateToolTip(XYDataset dataset, int seriesIndex, int itemIndex) {
            return "Test tooltip!";
        }
    }

    private static XYDataset createDataset() {
        TimeSeries timeseries = new TimeSeries("Test", org.jfree.data.time.Month.class);
        timeseries.add(new Month(8, 2014), 100D);
        TimeSeriesCollection collection = new TimeSeriesCollection();
        collection.addSeries(timeseries);
        return collection;
    }

}

converge
Posts: 30
Joined: Wed Jun 16, 2004 3:00 pm

Re: Clone() Not Supported

Post by converge » Mon Aug 18, 2014 7:36 pm

I managed to "fix" the issue by changing all my "implements XYToolTipGenerator" classes to "extends StandardXYToolTipGenerator".

uvoigt
Posts: 168
Joined: Mon Aug 23, 2004 10:50 am
Location: Germany

Re: Clone() Not Supported

Post by uvoigt » Tue Aug 19, 2014 10:52 am

The reason is that your TestToolTipGenerator class does not implement the Clonable interface and it does not implement a public clone() method. Both are required for a class to be cloneable.

Your example works when changing the TestToolTipGenerator implementation as follows:

Code: Select all

    private static class TestToolTipGenerator    implements XYToolTipGenerator, PublicCloneable    {

        @Override
        public String generateToolTip(XYDataset dataset, int seriesIndex, int itemIndex) {
            return "Test tooltip!";
        }

        @Override
        public Object clone()
            throws CloneNotSupportedException  {
            return super.clone();
        }
    }

converge
Posts: 30
Joined: Wed Jun 16, 2004 3:00 pm

Re: Clone() Not Supported

Post by converge » Wed Aug 20, 2014 1:26 pm

Thanks. That makes sense.

Locked