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