Reputation: 722
I have the following JSON serialized from the a Vaadin Charts default theme:
{
"colors":[
{
"color":"#2f7ed8"
},
{
"color":"#0d233a"
},
{
"color":"#8bbc21"
},
{
"color":"#910000"
},
{
"color":"#1aadce"
},
{
"color":"#492970"
},
{
"color":"#f28f43"
},
{
"color":"#77a1e5"
},
{
"color":"#c42525"
},
{
"color":"#a6c96a"
}
],
"chart":{
"backgroundcolor":{
"color":"#FFFFFF"
},
"plotBackgroundcolor":{
"color":"rgba(255,255,255,0.00)"
},
"plotBackgroundImage":"",
"plotShadow":false,
"plotBorderWidth":0,
"plotBordercolor":{
"color":"#C0C0C0"
},
"className":"",
"style":{
"fontFamily":"\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif",
"fontSize":"12px"
}
},
"title":{
"style":{
"color":{
"color":"#3E576F"
},
"fontWeight":"NORMAL",
"fontSize":"16px"
}
},
"subtitle":{
"style":{
"color":{
"color":"#6D869F"
},
"fontWeight":"NORMAL",
"fontSize":"12px"
}
},
"xAxis":{
"linecolor":{
"color":"#C0D0E0"
},
"lineWidth":1,
"tickcolor":{
"color":"#C0D0E0"
},
"gridLinecolor":{
"color":"#C0C0C0"
},
"gridLineWidth":0,
"alternateGridcolor":{
"color":"rgba(255,255,255,0.00)"
},
"title":{
"style":{
"color":{
"color":"#3E576F"
},
"fontWeight":"NORMAL"
}
},
"subtitle":{
"style":{
"color":{
"color":"#666666"
},
"fontWeight":"NORMAL",
"fontSize":"10px"
}
},
"labels":{
"style":{
"color":{
"color":"#666666"
},
"fontWeight":"NORMAL",
"fontSize":"11px"
}
}
},
"yAxis":{
"minorTickInterval":"NONE",
"linecolor":{
"color":"#C0D0E0"
},
"lineWidth":0,
"tickWidth":0,
"tickcolor":{
"color":"#C0D0E0"
},
"gridLinecolor":{
"color":"#C0C0C0"
},
"gridLineWidth":1,
"alternateGridcolor":{
"color":"rgba(255,255,255,0.00)"
},
"title":{
"style":{
"color":{
"color":"#3E576F"
},
"fontWeight":"NORMAL"
}
},
"subtitle":{
"style":{
"color":{
"color":"#666666"
},
"fontWeight":"NORMAL",
"fontSize":"10px"
}
},
"labels":{
"style":{
"color":{
"color":"#666666"
},
"fontWeight":"NORMAL",
"fontSize":"11px"
}
}
},
"labels":{
"style":{
}
},
"legend":{
"backgroundcolor":{
"color":"rgba(255,255,255,0.00)"
},
"bordercolor":{
"color":"#646464"
},
"borderRadius":5,
"itemHiddenStyle":{
"color":{
"color":"#CCC"
}
},
"itemHoverStyle":{
"color":{
"color":"#000"
}
},
"itemStyle":{
"color":{
"color":"#3E576F"
},
"position":"RELATIVE"
}
},
"tooltip":{
"backgroundcolor":{
"color":"rgba(255,255,255,0.85)"
},
"borderWidth":2,
"followPointer":false,
"style":{
"color":{
"color":"#333333"
}
}
},
"plotOptions":{
"area":{
"shadow":false
},
"arearange":{
"shadow":false
},
"areaspline":{
},
"areasplinerange":{
"shadow":false
},
"bar":{
"shadow":false
},
"boxplot":{
},
"bubble":{
},
"column":{
"shadow":false
},
"columnrange":{
},
"errorbar":{
},
"funnel":{
},
"gauge":{
},
"heatmap":{
},
"line":{
"shadow":false
},
"pie":{
"shadow":false
},
"polygon":{
},
"pyramid":{
},
"scatter":{
},
"series":{
},
"solidgauge":{
},
"spline":{
"shadow":false
},
"treemap":{
},
"waterfall":{
},
"candlestick":{
},
"flags":{
},
"ohlc":{
}
},
"credits":{
}
}
And this is the theme class:
/**
* Theme class for Chart. This is empty theme, and only defines the structure of
* Theme. Inherit own Theme class, or use Themes inherited from this class to
* theme your Charts.
*
* @see VaadinTheme
*/
public class Theme extends AbstractConfigurationObject {
private Color[] colors; //This is an interface and is what is causing problems
private ChartStyle chart = new ChartStyle();
private StyleWrapper title = new StyleWrapper();
private StyleWrapper subtitle = new StyleWrapper();
private AxisStyle xAxis = new AxisStyle();
private AxisStyle yAxis = new AxisStyle();
private StyleWrapper labels = new StyleWrapper();
private LegendStyle legend = new LegendStyle();
private TooltipStyle tooltip = new TooltipStyle();
private PlotOptionsStyle plotOptions = new PlotOptionsStyle();
private Credits credits = new Credits();
//Getters and setters
}
The idea is to convert a JSON like that to a Vaadin Charts theme in order to allow the admin of my application to theme the charts. However GSON throws the following exception:
Caused by: java.lang.RuntimeException: Unable to invoke no-args constructor for interface com.vaadin.addon.charts.model.style.Color. Register an InstanceCreator with Gson for this type may fix this problem.
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:226)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:207)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:217)
at com.google.gson.Gson.fromJson(Gson.java:861)
at com.google.gson.Gson.fromJson(Gson.java:799)
at es.cic.luca.web.vaadin.elementos.GeneradorGrafica.crearThemeFromJson(GeneradorGrafica.java:1214)
at es.cic.luca.web.vaadin.elementos.GeneradorGrafica.generar(GeneradorGrafica.java:93)
at es.cic.luca.web.vaadin.vista.CreacionGraficasVista.lambda$1(CreacionGraficasVista.java:426)
at es.cic.luca.web.vaadin.vista.CreacionGraficasVista$$Lambda$82/1320668893.buttonClick(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
... 83 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:48)
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:223)
... 99 more
Caused by: java.lang.InstantiationException: com.vaadin.addon.charts.model.style.Color
at sun.misc.Unsafe.allocateInstance(Native Method)
... 105 more
I created the class ColorInstanceCreator
to solve the problem:
public class ColorInstanceCreator implements InstanceCreator<Color> {
@Override
public Color createInstance(Type type) {
return new SolidColor("");
}
}
And make GSON to use it:
Gson gson = new GsonBuilder().registerTypeAdapter(Color.class,new ColorInstanceCreator()).create();
This solves the problem but all the colors in the converted class are black (#000000
).
I also tried to create a custom serializer/deserializer the I found here, but it doesn't work:
Caused by: com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper
at es.cic.luca.web.vaadin.elementos.GeneradorGrafica$InterfaceAdapter.get(GeneradorGrafica.java:1248)
at es.cic.luca.web.vaadin.elementos.GeneradorGrafica$InterfaceAdapter.deserialize(GeneradorGrafica.java:1231)
at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:217)
at com.google.gson.Gson.fromJson(Gson.java:861)
at com.google.gson.Gson.fromJson(Gson.java:799)
at es.cic.luca.web.vaadin.elementos.GeneradorGrafica.crearThemeFromJson(GeneradorGrafica.java:1213)
at es.cic.luca.web.vaadin.elementos.GeneradorGrafica.generar(GeneradorGrafica.java:93)
at es.cic.luca.web.vaadin.vista.CreacionGraficasVista.lambda$1(CreacionGraficasVista.java:426)
at es.cic.luca.web.vaadin.vista.CreacionGraficasVista$$Lambda$124/1623517905.buttonClick(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
... 83 more
What more can I do to solve my problem?
Upvotes: 0
Views: 237
Reputation: 722
I adapted this code to solve my problem and here is the solution:
final class ColorAdapter implements JsonDeserializer<Color> {
public Color deserialize(JsonElement elem, Type interfaceType,
JsonDeserializationContext context) throws JsonParseException {
Color toReturn = null;
if(elem instanceof JsonPrimitive) {
final JsonPrimitive color = elem.getAsJsonPrimitive();
toReturn = new SolidColor(color.getAsString());
} else {
final JsonObject wrapper = (JsonObject) elem;
final JsonElement data = get(wrapper, "color");
toReturn = context.deserialize(data, Color.class);
}
return toReturn;
}
private JsonElement get(final JsonObject wrapper, String memberName) {
final JsonElement elem = wrapper.get(memberName);
if (elem == null)
throw new JsonParseException(
"no '"
+ memberName
+ "' member found in what was expected to be an interface wrapper");
return elem;
}
}
Upvotes: 1