Clone exception when copying ChartPanel to clipboard
Clone exception when copying ChartPanel to clipboard
I am in the process of upgrading from v. 1.0.14 to 1.0.19 and am getting a CloneNotSupportedException when I try to copy a ChartPanel to the system clipboard in Windows via ChartPanel.doCopy().
java.lang.RuntimeException: java.lang.CloneNotSupportedException: Failed to clone.
at org.jfree.chart.util.CloneUtils.cloneMapValues(CloneUtils.java:100)
at org.jfree.chart.renderer.AbstractRenderer.clone(AbstractRenderer.java:3255)
at org.jfree.chart.renderer.xy.AbstractXYItemRenderer.clone(AbstractXYItemRenderer.java:1484)
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.chart.JFreeChart.clone(JFreeChart.java:1721)
at org.jfree.chart.ChartTransferable.<init>(ChartTransferable.java:155)
at org.jfree.chart.ChartPanel.doCopy(ChartPanel.java:2695)
The exception ultimately stems from AbstractRenderer.clone() where it's trying to clone the itemLabelFontMap, which is a Map<Integer,Font>: clone.itemLabelFontMap = CloneUtils.cloneMapValues(this.itemLabelFontMap).
However, java.awt.Font does not implement the Cloneable interface, so the exception is thrown by CloneUtils.cloneMapValues().
In 1.0.14, this was stored as an ObjectList, and the clone method did the following (which didn't give me any problems)
clone.itemLabelFontList = (ObjectList) this.itemLabelFontList.clone();
Is this a bug in 1.0.19, or is there something I'm missing here?
java.lang.RuntimeException: java.lang.CloneNotSupportedException: Failed to clone.
at org.jfree.chart.util.CloneUtils.cloneMapValues(CloneUtils.java:100)
at org.jfree.chart.renderer.AbstractRenderer.clone(AbstractRenderer.java:3255)
at org.jfree.chart.renderer.xy.AbstractXYItemRenderer.clone(AbstractXYItemRenderer.java:1484)
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.chart.JFreeChart.clone(JFreeChart.java:1721)
at org.jfree.chart.ChartTransferable.<init>(ChartTransferable.java:155)
at org.jfree.chart.ChartPanel.doCopy(ChartPanel.java:2695)
The exception ultimately stems from AbstractRenderer.clone() where it's trying to clone the itemLabelFontMap, which is a Map<Integer,Font>: clone.itemLabelFontMap = CloneUtils.cloneMapValues(this.itemLabelFontMap).
However, java.awt.Font does not implement the Cloneable interface, so the exception is thrown by CloneUtils.cloneMapValues().
In 1.0.14, this was stored as an ObjectList, and the clone method did the following (which didn't give me any problems)
clone.itemLabelFontList = (ObjectList) this.itemLabelFontList.clone();
Is this a bug in 1.0.19, or is there something I'm missing here?
Re: Clone exception when copying ChartPanel to clipboard
I think it's a bug...
Thinking about a quadcopter? Check this [url=hhttp://djibestdrones.com/dji-mavic-air-review/]Mavic Air 4 review[/url] before you make a purchase!
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: Clone exception when copying ChartPanel to clipboard
I agree. Instances of java.awt.Font are immutable AFAICS, so there is no need to clone anything.alex80 wrote:I think it's a bug...
I am wondering more and more whether the change from ObjectList to Map<Integer, AnObject> that was implemented a few versions ago was a good design decision.
Re: Clone exception when copying ChartPanel to clipboard
Do you happen to know offhand with what version that started?
My solution is either to go back to 1.0.14 (or later but before the change), or I've been playing around with making a CloneableFont class and subclassing the XYLineAndShapeRenderer to override the setXXX(Font) methods to use the CloneableFonts instead, which I'd rather not have to do if I can avoid it.
I also noticed while digging into the ChartPanel.doCopy() method, that there's a ChartTransferable class whose constructors take a cloneData boolean, but when I looked at the code, it's not doing anything with that boolean and always clones.
My solution is either to go back to 1.0.14 (or later but before the change), or I've been playing around with making a CloneableFont class and subclassing the XYLineAndShapeRenderer to override the setXXX(Font) methods to use the CloneableFonts instead, which I'd rather not have to do if I can avoid it.
I also noticed while digging into the ChartPanel.doCopy() method, that there's a ChartTransferable class whose constructors take a cloneData boolean, but when I looked at the code, it's not doing anything with that boolean and always clones.
Re: Clone exception when copying ChartPanel to clipboard
Tried my CloneableFont and subclassing the renderer approach for giggles. It worked for the fonts, but now I'm running into the same issue for ItemLabelPosition objects. I have a feeling there will be more, so I'm going to ditch 1.0.19 and go back to before the Maps replaced the ObjectLists.
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: Clone exception when copying ChartPanel to clipboard
I came across this change after reading this thread.lynnskii wrote:Do you happen to know offhand with what version that started?
I can´t tell when this change was introduced. According to the thread above, David made this change while fixing a bug in the ObjectList class. However, the documentation of this class doesn´t mention a change after 2004.
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Re: Clone exception when copying ChartPanel to clipboard
Hi,
It's definitely a bug. I modified the unit test for cloning renderers to expose the bug, and fixed it for the upcoming 1.0.20 release. Here's the fix:
It's definitely a bug. I modified the unit test for cloning renderers to expose the bug, and fixed it for the upcoming 1.0.20 release. Here's the fix:
Code: Select all
# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- AbstractRenderer.java (8a2e412)
+++ AbstractRenderer.java (b66a321)
@@ -93,6 +93,7 @@
* 03-Jul-2013 : Use ParamChecks (DG);
* 09-Apr-2014 : Remove use of ObjectList (DG);
* 24-Aug-2014 : Add begin/endElementGroup() (DG);
+ * 25-Apr-2016 : Fix cloning test failuer (DG);
*
*/
@@ -3286,7 +3287,7 @@
// 'itemLabelFont' : immutable, no need to clone reference
if (this.itemLabelFontMap != null) {
clone.itemLabelFontMap
- = CloneUtils.cloneMapValues(this.itemLabelFontMap);
+ = new HashMap<Integer, Font>(this.itemLabelFontMap);
}
// 'baseItemLabelFont' : immutable, no need to clone reference
@@ -3320,7 +3321,8 @@
clone.legendShapeList = (ShapeList) this.legendShapeList.clone();
}
if (this.legendTextFontMap != null) {
- clone.legendTextFontMap = CloneUtils.cloneMapValues(
+ // Font objects are immutable so just shallow copy the map
+ clone.legendTextFontMap = new HashMap<Integer, Font>(
this.legendTextFontMap);
}
if (this.legendTextPaint != null) {
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


Re: Clone exception when copying ChartPanel to clipboard
David,
While you're in there fixing that, I experienced the same issue when trying to clone the maps with ItemLabelPosition, which is Serializable but not Cloneable. You might check for any others. Thanks.
// 'postiveItemLabelAnchor' : immutable, no need to clone reference
if (this.positiveItemLabelPositionMap != null) {
clone.positiveItemLabelPositionMap = CloneUtils.cloneMapValues(
this.positiveItemLabelPositionMap);
}
// 'baseItemLabelAnchor' : immutable, no need to clone reference
// 'negativeItemLabelAnchor' : immutable, no need to clone reference
if (this.negativeItemLabelPositionMap != null) {
clone.negativeItemLabelPositionMap = CloneUtils.cloneMapValues(
this.negativeItemLabelPositionMap);
}
// 'baseNegativeItemLabelAnchor' : immutable, no need to clone reference
While you're in there fixing that, I experienced the same issue when trying to clone the maps with ItemLabelPosition, which is Serializable but not Cloneable. You might check for any others. Thanks.
// 'postiveItemLabelAnchor' : immutable, no need to clone reference
if (this.positiveItemLabelPositionMap != null) {
clone.positiveItemLabelPositionMap = CloneUtils.cloneMapValues(
this.positiveItemLabelPositionMap);
}
// 'baseItemLabelAnchor' : immutable, no need to clone reference
// 'negativeItemLabelAnchor' : immutable, no need to clone reference
if (this.negativeItemLabelPositionMap != null) {
clone.negativeItemLabelPositionMap = CloneUtils.cloneMapValues(
this.negativeItemLabelPositionMap);
}
// 'baseNegativeItemLabelAnchor' : immutable, no need to clone reference
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Re: Clone exception when copying ChartPanel to clipboard
Sure, I'll add those cases to the JUnit test first. It will be fixed for the next release.
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader

