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