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