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