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