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