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