RadialGradientPaintPropertyEditor.java
001 /*
002  * Copyright 2008-2017 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package griffon.swing.editors;
017 
018 import griffon.core.editors.AbstractPropertyEditor;
019 import griffon.metadata.PropertyEditorFor;
020 
021 import java.awt.Color;
022 import java.awt.MultipleGradientPaint;
023 import java.awt.RadialGradientPaint;
024 import java.lang.reflect.Field;
025 import java.util.List;
026 import java.util.Map;
027 
028 import static griffon.util.GriffonNameUtils.isBlank;
029 
030 /**
031  @author Andres Almiray
032  @since 2.0.0
033  */
034 @PropertyEditorFor(RadialGradientPaint.class)
035 public class RadialGradientPaintPropertyEditor extends AbstractPropertyEditor {
036     @Override
037     public String getAsText() {
038         if (null == getValue()) return null;
039         RadialGradientPaint p = (RadialGradientPaintgetValue();
040         return new StringBuilder()
041             .append(p.getCenterPoint().getX())
042             .append(", ")
043             .append(p.getCenterPoint().getY())
044             .append(", ")
045             .append(p.getRadius())
046             .append(", ")
047             .append(p.getFocusPoint().getX())
048             .append(", ")
049             .append(p.getFocusPoint().getY())
050             .append(", ")
051             .append(formatFractions(p.getFractions()))
052             .append(", ")
053             .append(formatColors(p.getColors()))
054             .append(", ")
055             .append(p.getCycleMethod().name())
056             .toString();
057     }
058 
059     protected String formatFractions(float[] fractions) {
060         StringBuilder b = new StringBuilder("[");
061         boolean first = true;
062 
063         for (float f : fractions) {
064             if (first) {
065                 first = false;
066             else {
067                 b.append(":");
068             }
069             b.append(f);
070         }
071         return b.append("]").toString();
072     }
073 
074     protected String formatColors(Color[] colors) {
075         StringBuilder b = new StringBuilder("[");
076         boolean first = true;
077 
078         for (Color c : colors) {
079             if (first) {
080                 first = false;
081             else {
082                 b.append(":");
083             }
084             b.append(ColorPropertyEditor.format(c));
085         }
086         return b.append("]").toString();
087     }
088 
089     @Override
090     protected void setValueInternal(Object value) {
091         if (null == value) {
092             super.setValueInternal(null);
093         else if (value instanceof CharSequence) {
094             handleAsString(String.valueOf(value));
095         else if (value instanceof List) {
096             handleAsList((Listvalue);
097         else if (value instanceof Map) {
098             handleAsMap((Mapvalue);
099         else if (value instanceof RadialGradientPaint) {
100             super.setValueInternal(value);
101         else {
102             throw illegalValue(value, RadialGradientPaint.class);
103         }
104     }
105 
106     protected void handleAsString(String str) {
107         if (isBlank(str)) {
108             super.setValueInternal(null);
109             return;
110         }
111 
112         float cx = 0;
113         float cy = 0;
114         float radius = 0;
115         float fx = 0;
116         float fy = 0;
117         float[] fractions = null;
118         Color[] colors = null;
119         MultipleGradientPaint.CycleMethod cyclicMethod = MultipleGradientPaint.CycleMethod.NO_CYCLE;
120         String[] parts = str.split(",");
121         switch (parts.length) {
122             case 8:
123                 cyclicMethod = parseCyclicMethod(str, parts[7]);
124             case 7:
125                 cx = parseValue(parts[0]);
126                 cy = parseValue(parts[1]);
127                 radius = parseValue(parts[2]);
128                 fx = parseValue(parts[3]);
129                 fy = parseValue(parts[4]);
130                 fractions = parseFractions(str, parts[5].trim());
131                 colors = parseColors(str, parts[6].trim());
132                 if (fractions.length != colors.length) {
133                     throw illegalValue(str, RadialGradientPaint.class);
134                 }
135                 super.setValueInternal(new RadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cyclicMethod));
136                 break;
137             default:
138                 throw illegalValue(str, RadialGradientPaint.class);
139         }
140     }
141 
142     protected void handleAsList(List<?> list) {
143         if(list.isEmpty()) {
144             super.setValueInternal(null);
145             return;
146         }
147 
148         float cx = 0;
149         float cy = 0;
150         float radius = 0;
151         float fx = 0;
152         float fy = 0;
153         float[] fractions = null;
154         Color[] colors = null;
155         MultipleGradientPaint.CycleMethod cyclicMethod = MultipleGradientPaint.CycleMethod.NO_CYCLE;
156         switch (list.size()) {
157             case 8:
158                 cyclicMethod = parseCyclicMethod(list, String.valueOf(list.get(7)).trim());
159             case 7:
160                 cx = parseValue(list.get(0));
161                 cy = parseValue(list.get(1));
162                 radius = parseValue(list.get(2));
163                 fx = parseValue(list.get(3));
164                 fy = parseValue(list.get(4));
165                 fractions = parseFractions(list, list.get(5));
166                 colors = parseColors(list, list.get(6));
167                 if (fractions.length != colors.length) {
168                     throw illegalValue(list, RadialGradientPaint.class);
169                 }
170                 super.setValueInternal(new RadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cyclicMethod));
171                 break;
172             default:
173                 throw illegalValue(list, RadialGradientPaint.class);
174         }
175     }
176 
177     protected void handleAsMap(Map<?, ?> map) {
178         if(map.isEmpty()) {
179             super.setValueInternal(null);
180             return;
181         }
182 
183         float cx = (FloatgetMapValue(map, "cx"0f);
184         float cy = (FloatgetMapValue(map, "cy"0f);
185         float radius = (FloatgetMapValue(map, "radius"0f);
186         float fx = (FloatgetMapValue(map, "fx"0f);
187         float fy = (FloatgetMapValue(map, "fy"0f);
188         MultipleGradientPaint.CycleMethod cyclicMethod = MultipleGradientPaint.CycleMethod.NO_CYCLE;
189 
190         float[] fractions = parseFractions(map, map.get("fractions"));
191         Color[] colors = parseColors(map, map.get("colors"));
192         if (fractions.length != colors.length) {
193             throw illegalValue(map, RadialGradientPaint.class);
194         }
195         Object cyclicValue = map.get("cycle");
196         if (null != cyclicValue) {
197             cyclicMethod = parseCyclicMethod(map, String.valueOf(cyclicValue));
198         }
199 
200         super.setValueInternal(new RadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cyclicMethod));
201     }
202 
203     protected float[] parseFractions(Object source, Object obj) {
204         if (obj instanceof CharSequence) {
205             return parseFractions(source, String.valueOf(obj).trim());
206         else if (obj instanceof List) {
207             return parseFractions(source, (Listobj);
208         }
209         throw illegalValue(source, RadialGradientPaint.class);
210     }
211 
212     protected float[] parseFractions(Object source, String str) {
213         if (!str.startsWith("["|| !str.endsWith("]")) {
214             throw illegalValue(source, RadialGradientPaint.class);
215         }
216 
217         String[] strs = str.substring(1, str.length() 1).split(":");
218         float[] fractions = new float[strs.length];
219         for (int i = 0; i < strs.length; i++) {
220             fractions[i= parseValue(strs[i]);
221         }
222 
223         return fractions;
224     }
225 
226     protected float[] parseFractions(Object source, List<?> list) {
227         float[] fractions = new float[list.size()];
228         for (int i = 0; i < list.size(); i++) {
229             fractions[i= parseValue(list.get(i));
230         }
231 
232         return fractions;
233     }
234 
235     protected Color[] parseColors(Object source, Object obj) {
236         if (obj instanceof CharSequence) {
237             return parseColors(source, String.valueOf(obj).trim());
238         else if (obj instanceof List) {
239             return parseColors(source, (Listobj);
240         }
241         throw illegalValue(source, RadialGradientPaint.class);
242     }
243 
244     protected Color[] parseColors(Object source, String str) {
245         if (!str.startsWith("["|| !str.endsWith("]")) {
246             throw illegalValue(source, RadialGradientPaint.class);
247         }
248 
249         String[] strs = str.substring(1, str.length() 1).split(":");
250         Color[] colors = new Color[strs.length];
251         ColorPropertyEditor colorEditor = new ColorPropertyEditor();
252         for (int i = 0; i < strs.length; i++) {
253             try {
254                 colorEditor.setValueInternal(strs[i]);
255                 colors[i(ColorcolorEditor.getValue();
256             catch (Exception e) {
257                 throw illegalValue(strs[i], RadialGradientPaint.class);
258             }
259         }
260 
261         return colors;
262     }
263 
264     protected Color[] parseColors(Object source, List<?> list) {
265         Color[] colors = new Color[list.size()];
266         ColorPropertyEditor colorEditor = new ColorPropertyEditor();
267         for (int i = 0; i < list.size(); i++) {
268             try {
269                 colorEditor.setValueInternal(list.get(i));
270                 colors[i(ColorcolorEditor.getValue();
271             catch (Exception e) {
272                 throw illegalValue(list.get(i), RadialGradientPaint.class, e);
273             }
274         }
275 
276         return colors;
277     }
278 
279     protected MultipleGradientPaint.CycleMethod parseCyclicMethod(Object source, String str) {
280         try {
281             Field cyclicMethodField = MultipleGradientPaint.CycleMethod.class.getDeclaredField(str.toUpperCase().trim());
282             return (MultipleGradientPaint.CycleMethodcyclicMethodField.get(null);
283         catch (NoSuchFieldException | IllegalAccessException e) {
284             throw illegalValue(source, RadialGradientPaint.class, e);
285         }
286     }
287 
288     protected float parse(String val) {
289         try {
290             return Float.parseFloat(val.trim());
291         catch (NumberFormatException e) {
292             throw illegalValue(val, RadialGradientPaint.class, e);
293         }
294     }
295 
296     protected float parseValue(Object value) {
297         if (value instanceof CharSequence) {
298             return parse(String.valueOf(value));
299         else if (value instanceof Number) {
300             return parse((Numbervalue);
301         }
302         throw illegalValue(value, RadialGradientPaint.class);
303     }
304 
305     protected float parse(Number val) {
306         return val.floatValue();
307     }
308 
309     protected Object getMapValue(Map<?, ?> map, String key, Object defaultValue) {
310         Object val = map.get(key);
311         if (null == val) {
312             return defaultValue;
313         else if (val instanceof CharSequence) {
314             return parse(String.valueOf(val));
315         else if (val instanceof Number) {
316             return parse((Numberval);
317         }
318         throw illegalValue(map, RadialGradientPaint.class);
319     }
320 }