ColorPropertyEditor.java
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.javafx.editors;
017 
018 import griffon.core.editors.AbstractPropertyEditor;
019 import griffon.core.formatters.Formatter;
020 import griffon.core.formatters.ParseException;
021 import griffon.javafx.formatters.ColorFormatter;
022 import griffon.metadata.PropertyEditorFor;
023 import javafx.scene.paint.Color;
024 
025 import java.util.ArrayList;
026 import java.util.List;
027 import java.util.Map;
028 
029 import static griffon.util.GriffonNameUtils.isBlank;
030 
031 
032 /**
033  @author Andres Almiray
034  */
035 @PropertyEditorFor(Color.class)
036 public class ColorPropertyEditor extends AbstractPropertyEditor {
037     public static String format(Color color) {
038         return ColorFormatter.LONG.format(color);
039     }
040 
041     @Override
042     public String getAsText() {
043         if (null == getValue()) return null;
044         return isBlank(getFormat()) ? format((ColorgetValueInternal()) : getFormattedValue();
045     }
046 
047     protected void setValueInternal(Object value) {
048         if (null == value) {
049             super.setValueInternal(null);
050         else if (value instanceof CharSequence) {
051             handleAsString(String.valueOf(value).trim());
052         else if (value instanceof List) {
053             handleAsList((Listvalue);
054         else if (value instanceof Map) {
055             handleAsMap((Mapvalue);
056         else if (value instanceof Number) {
057             handleAsNumber((Numbervalue);
058         else if (value instanceof Color) {
059             super.setValueInternal(value);
060         else {
061             throw illegalValue(value, Color.class);
062         }
063     }
064 
065     @Override
066     protected Formatter<Color> resolveFormatter() {
067         return !isBlank(getFormat()) ? ColorFormatter.getInstance(getFormat()) null;
068     }
069 
070     private void handleAsString(String str) {
071         if (isBlank(str)) {
072             super.setValueInternal(null);
073             return;
074         }
075         try {
076             super.setValueInternal(ColorFormatter.parseColor(str));
077         catch (ParseException e) {
078             throw illegalValue(str, Color.class, e);
079         }
080     }
081 
082     private void handleAsList(List<?> list) {
083         if (list.isEmpty()) {
084             super.setValueInternal(null);
085             return;
086         }
087 
088         List<Object> values = new ArrayList<>();
089         values.addAll(list);
090         switch (list.size()) {
091             case 3:
092                 values.add(1d);
093                 break;
094             case 4:
095                 // ok
096                 break;
097             default:
098                 throw illegalValue(list, Color.class);
099         }
100         for (int i = 0, valuesSize = values.size(); i < valuesSize; i++) {
101             Object val = values.get(i);
102             if (val instanceof Number) {
103                 values.set(i, parse((Numberval));
104             else if (val instanceof CharSequence) {
105                 values.set(i, parse(String.valueOf(val)));
106             else {
107                 throw illegalValue(list, Color.class);
108             }
109         }
110         super.setValueInternal(
111             new Color(
112                 (Doublevalues.get(0),
113                 (Doublevalues.get(1),
114                 (Doublevalues.get(2),
115                 (Doublevalues.get(3)
116             )
117         );
118     }
119 
120     private void handleAsMap(Map<?, ?> map) {
121         if (map.isEmpty()) {
122             super.setValueInternal(null);
123             return;
124         }
125 
126         double r = getMapValue(map, "red"0d);
127         double g = getMapValue(map, "green"0d);
128         double b = getMapValue(map, "blue"0d);
129         double a = getMapValue(map, "alpha"1d);
130         super.setValueInternal(new Color(r, g, b, a));
131     }
132 
133     private double parse(String val) {
134         try {
135             return (Integer.parseInt(String.valueOf(val).trim()160xFF255d;
136         catch (NumberFormatException e) {
137             throw illegalValue(val, Color.class, e);
138         }
139     }
140 
141     private double parse(Number val) {
142         return val.doubleValue();
143     }
144 
145     private double getMapValue(Map<?, ?> map, String key, double defaultValue) {
146         Object val = map.get(key);
147         if (null == valval = map.get(String.valueOf(key.charAt(0)));
148         if (null == val) {
149             return defaultValue;
150         else if (val instanceof CharSequence) {
151             return parse(String.valueOf(val));
152         else if (val instanceof Number) {
153             return parse((Numberval);
154         }
155         throw illegalValue(map, Color.class);
156     }
157 
158     private void handleAsNumber(Number value) {
159         double c = parse(value);
160         super.setValueInternal(new Color(c, c, c, 1d));
161     }
162 }