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