RadialGradientPaintPropertyEditor.java
001 /*
002  * Copyright 2008-2016 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     public String getAsText() {
037         if (null == getValue()) return null;
038         RadialGradientPaint p = (RadialGradientPaintgetValue();
039         return new StringBuilder()
040             .append(p.getCenterPoint().getX())
041             .append(", ")
042             .append(p.getCenterPoint().getY())
043             .append(", ")
044             .append(p.getRadius())
045             .append(", ")
046             .append(p.getFocusPoint().getX())
047             .append(", ")
048             .append(p.getFocusPoint().getY())
049             .append(", ")
050             .append(formatFractions(p.getFractions()))
051             .append(", ")
052             .append(formatColors(p.getColors()))
053             .append(", ")
054             .append(p.getCycleMethod().name())
055             .toString();
056     }
057 
058     protected String formatFractions(float[] fractions) {
059         StringBuilder b = new StringBuilder("[");
060         boolean first = true;
061 
062         for (float f : fractions) {
063             if (first) {
064                 first = false;
065             else {
066                 b.append(":");
067             }
068             b.append(f);
069         }
070         return b.append("]").toString();
071     }
072 
073     protected String formatColors(Color[] colors) {
074         StringBuilder b = new StringBuilder("[");
075         boolean first = true;
076 
077         for (Color c : colors) {
078             if (first) {
079                 first = false;
080             else {
081                 b.append(":");
082             }
083             b.append(ColorPropertyEditor.format(c));
084         }
085         return b.append("]").toString();
086     }
087 
088     protected void setValueInternal(Object value) {
089         if (null == value) {
090             super.setValueInternal(null);
091         else if (value instanceof CharSequence) {
092             handleAsString(String.valueOf(value));
093         else if (value instanceof List) {
094             handleAsList((Listvalue);
095         else if (value instanceof Map) {
096             handleAsMap((Mapvalue);
097         else if (value instanceof RadialGradientPaint) {
098             super.setValueInternal(value);
099         else {
100             throw illegalValue(value, RadialGradientPaint.class);
101         }
102     }
103 
104     protected void handleAsString(String str) {
105         if (isBlank(str)) {
106             super.setValueInternal(null);
107             return;
108         }
109 
110         float cx = 0;
111         float cy = 0;
112         float radius = 0;
113         float fx = 0;
114         float fy = 0;
115         float[] fractions = null;
116         Color[] colors = null;
117         MultipleGradientPaint.CycleMethod cyclicMethod = MultipleGradientPaint.CycleMethod.NO_CYCLE;
118         String[] parts = str.split(",");
119         switch (parts.length) {
120             case 8:
121                 cyclicMethod = parseCyclicMethod(str, parts[7]);
122             case 7:
123                 cx = parseValue(parts[0]);
124                 cy = parseValue(parts[1]);
125                 radius = parseValue(parts[2]);
126                 fx = parseValue(parts[3]);
127                 fy = parseValue(parts[4]);
128                 fractions = parseFractions(str, parts[5].trim());
129                 colors = parseColors(str, parts[6].trim());
130                 if (fractions.length != colors.length) {
131                     throw illegalValue(str, RadialGradientPaint.class);
132                 }
133                 super.setValueInternal(new RadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cyclicMethod));
134                 break;
135             default:
136                 throw illegalValue(str, RadialGradientPaint.class);
137         }
138     }
139 
140     protected void handleAsList(List<?> list) {
141         if(list.isEmpty()) {
142             super.setValueInternal(null);
143             return;
144         }
145 
146         float cx = 0;
147         float cy = 0;
148         float radius = 0;
149         float fx = 0;
150         float fy = 0;
151         float[] fractions = null;
152         Color[] colors = null;
153         MultipleGradientPaint.CycleMethod cyclicMethod = MultipleGradientPaint.CycleMethod.NO_CYCLE;
154         switch (list.size()) {
155             case 8:
156                 cyclicMethod = parseCyclicMethod(list, String.valueOf(list.get(7)).trim());
157             case 7:
158                 cx = parseValue(list.get(0));
159                 cy = parseValue(list.get(1));
160                 radius = parseValue(list.get(2));
161                 fx = parseValue(list.get(3));
162                 fy = parseValue(list.get(4));
163                 fractions = parseFractions(list, list.get(5));
164                 colors = parseColors(list, list.get(6));
165                 if (fractions.length != colors.length) {
166                     throw illegalValue(list, RadialGradientPaint.class);
167                 }
168                 super.setValueInternal(new RadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cyclicMethod));
169                 break;
170             default:
171                 throw illegalValue(list, RadialGradientPaint.class);
172         }
173     }
174 
175     protected void handleAsMap(Map<?, ?> map) {
176         if(map.isEmpty()) {
177             super.setValueInternal(null);
178             return;
179         }
180 
181         float cx = (FloatgetMapValue(map, "cx"0f);
182         float cy = (FloatgetMapValue(map, "cy"0f);
183         float radius = (FloatgetMapValue(map, "radius"0f);
184         float fx = (FloatgetMapValue(map, "fx"0f);
185         float fy = (FloatgetMapValue(map, "fy"0f);
186         MultipleGradientPaint.CycleMethod cyclicMethod = MultipleGradientPaint.CycleMethod.NO_CYCLE;
187 
188         float[] fractions = parseFractions(map, map.get("fractions"));
189         Color[] colors = parseColors(map, map.get("colors"));
190         if (fractions.length != colors.length) {
191             throw illegalValue(map, RadialGradientPaint.class);
192         }
193         Object cyclicValue = map.get("cycle");
194         if (null != cyclicValue) {
195             cyclicMethod = parseCyclicMethod(map, String.valueOf(cyclicValue));
196         }
197 
198         super.setValueInternal(new RadialGradientPaint(cx, cy, radius, fx, fy, fractions, colors, cyclicMethod));
199     }
200 
201     protected float[] parseFractions(Object source, Object obj) {
202         if (obj instanceof CharSequence) {
203             return parseFractions(source, String.valueOf(obj).trim());
204         else if (obj instanceof List) {
205             return parseFractions(source, (Listobj);
206         }
207         throw illegalValue(source, RadialGradientPaint.class);
208     }
209 
210     protected float[] parseFractions(Object source, String str) {
211         if (!str.startsWith("["|| !str.endsWith("]")) {
212             throw illegalValue(source, RadialGradientPaint.class);
213         }
214 
215         String[] strs = str.substring(1, str.length() 1).split(":");
216         float[] fractions = new float[strs.length];
217         for (int i = 0; i < strs.length; i++) {
218             fractions[i= parseValue(strs[i]);
219         }
220 
221         return fractions;
222     }
223 
224     protected float[] parseFractions(Object source, List<?> list) {
225         float[] fractions = new float[list.size()];
226         for (int i = 0; i < list.size(); i++) {
227             fractions[i= parseValue(list.get(i));
228         }
229 
230         return fractions;
231     }
232 
233     protected Color[] parseColors(Object source, Object obj) {
234         if (obj instanceof CharSequence) {
235             return parseColors(source, String.valueOf(obj).trim());
236         else if (obj instanceof List) {
237             return parseColors(source, (Listobj);
238         }
239         throw illegalValue(source, RadialGradientPaint.class);
240     }
241 
242     protected Color[] parseColors(Object source, String str) {
243         if (!str.startsWith("["|| !str.endsWith("]")) {
244             throw illegalValue(source, RadialGradientPaint.class);
245         }
246 
247         String[] strs = str.substring(1, str.length() 1).split(":");
248         Color[] colors = new Color[strs.length];
249         ColorPropertyEditor colorEditor = new ColorPropertyEditor();
250         for (int i = 0; i < strs.length; i++) {
251             try {
252                 colorEditor.setValueInternal(strs[i]);
253                 colors[i(ColorcolorEditor.getValue();
254             catch (Exception e) {
255                 throw illegalValue(strs[i], RadialGradientPaint.class);
256             }
257         }
258 
259         return colors;
260     }
261 
262     protected Color[] parseColors(Object source, List<?> list) {
263         Color[] colors = new Color[list.size()];
264         ColorPropertyEditor colorEditor = new ColorPropertyEditor();
265         for (int i = 0; i < list.size(); i++) {
266             try {
267                 colorEditor.setValueInternal(list.get(i));
268                 colors[i(ColorcolorEditor.getValue();
269             catch (Exception e) {
270                 throw illegalValue(list.get(i), RadialGradientPaint.class, e);
271             }
272         }
273 
274         return colors;
275     }
276 
277     protected MultipleGradientPaint.CycleMethod parseCyclicMethod(Object source, String str) {
278         try {
279             Field cyclicMethodField = MultipleGradientPaint.CycleMethod.class.getDeclaredField(str.toUpperCase().trim());
280             return (MultipleGradientPaint.CycleMethodcyclicMethodField.get(null);
281         catch (NoSuchFieldException | IllegalAccessException e) {
282             throw illegalValue(source, RadialGradientPaint.class, e);
283         }
284     }
285 
286     protected float parse(String val) {
287         try {
288             return Float.parseFloat(val.trim());
289         catch (NumberFormatException e) {
290             throw illegalValue(val, RadialGradientPaint.class, e);
291         }
292     }
293 
294     protected float parseValue(Object value) {
295         if (value instanceof CharSequence) {
296             return parse(String.valueOf(value));
297         else if (value instanceof Number) {
298             return parse((Numbervalue);
299         }
300         throw illegalValue(value, RadialGradientPaint.class);
301     }
302 
303     protected float parse(Number val) {
304         return val.floatValue();
305     }
306 
307     protected Object getMapValue(Map<?, ?> map, String key, Object defaultValue) {
308         Object val = map.get(key);
309         if (null == val) {
310             return defaultValue;
311         else if (val instanceof CharSequence) {
312             return parse(String.valueOf(val));
313         else if (val instanceof Number) {
314             return parse((Numberval);
315         }
316         throw illegalValue(map, RadialGradientPaint.class);
317     }
318 }