| 
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.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 }
 |