| 
001 /*002  * Copyright 2008-2015 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 }
 |