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