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