modules/graphics/src/main/java/javafx/css/StyleConverter.java
Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
*** 23,56 ****
* questions.
*/
package javafx.css;
! import com.sun.javafx.css.converters.BooleanConverter;
! import com.sun.javafx.css.converters.ColorConverter;
! import com.sun.javafx.css.converters.DurationConverter;
! import com.sun.javafx.css.converters.EffectConverter;
! import com.sun.javafx.css.converters.EnumConverter;
! import com.sun.javafx.css.converters.FontConverter;
! import com.sun.javafx.css.converters.InsetsConverter;
! import com.sun.javafx.css.converters.PaintConverter;
! import com.sun.javafx.css.converters.SizeConverter;
! import com.sun.javafx.css.converters.StringConverter;
! import com.sun.javafx.css.converters.URLConverter;
import javafx.geometry.Insets;
import javafx.scene.effect.Effect;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.util.Duration;
/**
! * Converter converts {@code ParsedValue&tl;F,T>} from type F to type T. the
* {@link CssMetaData} API requires a {@code StyleConverter} which is used
* when computing a value for the {@see StyleableProperty}. There are
* a number of predefined converters which are accessible by the static
* methods of this class.
* @see ParsedValue
* @see StyleableProperty
* @since JavaFX 8.0
*/
public class StyleConverter<F, T> {
--- 23,83 ----
* questions.
*/
package javafx.css;
! import javafx.css.converter.BooleanConverter;
! import javafx.css.converter.ColorConverter;
! import javafx.css.converter.DeriveColorConverter;
! import javafx.css.converter.DeriveSizeConverter;
! import javafx.css.converter.DurationConverter;
! import javafx.css.converter.EffectConverter;
! import javafx.css.converter.EnumConverter;
! import javafx.css.converter.FontConverter;
! import javafx.css.converter.InsetsConverter;
! import javafx.css.converter.LadderConverter;
! import javafx.css.converter.PaintConverter;
! import javafx.css.converter.SizeConverter;
! import javafx.css.converter.StopConverter;
! import javafx.css.converter.StringConverter;
! import javafx.css.converter.URLConverter;
import javafx.geometry.Insets;
import javafx.scene.effect.Effect;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.util.Duration;
+ import com.sun.javafx.scene.layout.region.CornerRadiiConverter;
+ import com.sun.javafx.util.Logging;
+ import sun.util.logging.PlatformLogger;
+ import sun.util.logging.PlatformLogger.Level;
+
+ import java.io.DataInputStream;
+ import java.io.DataOutputStream;
+ import java.io.IOException;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.WeakHashMap;
+
+
/**
! * StyleConverter converts {@code ParsedValue&tl;F,T>} from type F to type T. The
* {@link CssMetaData} API requires a {@code StyleConverter} which is used
* when computing a value for the {@see StyleableProperty}. There are
* a number of predefined converters which are accessible by the static
* methods of this class.
+ *
+ * F is the type of the parsed value, T is the converted type of
+ * the ParsedValueImpl. For example, a converter from String to Color would
+ * be declared
+ * <p>
+ * <code>public Color convert(ParsedValueImpl<String,Color> value, Font font)</code>
+ * </p>
+ *
* @see ParsedValue
* @see StyleableProperty
* @since JavaFX 8.0
*/
public class StyleConverter<F, T> {
*** 183,188 ****
--- 210,539 ----
public static StyleConverter<ParsedValue[], String> getUrlConverter() {
return URLConverter.getInstance();
}
+
+
+ /**
+ * Convert from the constituent values to the target property type.
+ * Implemented by Types that have Keys with subKeys.
+ *
+ * @since 9
+ */
+ public T convert(Map<CssMetaData<? extends Styleable, ?>,Object> convertedValues) {
+ return null;
+ }
+
+ /**
+ *
+ * @since 9
+ */
+ public void writeBinary(DataOutputStream os, StringStore sstore)
+ throws IOException {
+
+ String cname = getClass().getName();
+ int index = sstore.addString(cname);
+ os.writeShort(index);
+ }
+
+ private static Map<ParsedValue, Object> cache;
+
+ /**
+ *
+ * @since 9
+ */
+ public static void clearCache() {
+ if (cache != null) {
+ cache.clear();
+ }
+ }
+
+ /**
+ *
+ * @since 9
+ */
+ protected T getCachedValue(ParsedValue key) {
+ if (cache != null) {
+ return (T)cache.get(key);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @since 9
+ */
+ protected void cacheValue(ParsedValue key, Object value) {
+ if (cache == null) cache = new WeakHashMap<>();
+ cache.put(key, value);
+ }
+
+ // map of StyleConverter class name to StyleConverter
+ private static Map<String,StyleConverter<?, ?>> tmap;
+
+ /**
+ *
+ * @since 9
+ */
+ @SuppressWarnings("rawtypes")
+ public static StyleConverter<?,?> readBinary(DataInputStream is, String[] strings)
+ throws IOException {
+
+ int index = is.readShort();
+ String cname = strings[index];
+
+ if (cname == null || cname.isEmpty()) return null;
+
+ if (cname.startsWith("com.sun.javafx.css.converters.")) {
+ // JavaFX 9: converter classes were moved from
+ // com.sun.javafx.css.converters.* to javafx.css.converter.*
+ // Note: the word 'converters' has become 'converter'.
+ cname = "javafx.css.converter." + cname.substring("com.sun.javafx.css.converters.".length());
+ }
+ if (cname.startsWith("javafx.css.converter.EnumConverter")) {
+ return (StyleConverter)javafx.css.converter.EnumConverter.readBinary(is, strings);
+ }
+
+ // Make a new entry in tmap, if necessary
+ if (tmap == null || !tmap.containsKey(cname)) {
+ StyleConverter<?,?> converter = getInstance(cname);
+ if (converter == null) {
+ final PlatformLogger logger = Logging.getCSSLogger();
+ if (logger.isLoggable(Level.SEVERE)) {
+ logger.severe("could not deserialize " + cname);
+ }
+ }
+ if (converter == null) {
+ System.err.println("could not deserialize " + cname);
+ }
+ if (tmap == null) tmap = new HashMap<String,StyleConverter<?,?>>();
+ tmap.put(cname, converter);
+ return converter;
+ }
+ return tmap.get(cname);
+ }
+
+ // package for unit test purposes
+ static StyleConverter<?,?> getInstance(final String converterClass) {
+
+ StyleConverter<?,?> styleConverter = null;
+
+ switch(converterClass) {
+ case "javafx.css.converter.BooleanConverter" :
+ styleConverter = javafx.css.converter.BooleanConverter.getInstance();
+ break;
+ case "javafx.css.converter.ColorConverter" :
+ styleConverter = javafx.css.converter.ColorConverter.getInstance();
+ break;
+ case "javafx.css.converter.CursorConverter" :
+ styleConverter = javafx.css.converter.CursorConverter.getInstance();
+ break;
+ case "javafx.css.converter.EffectConverter" :
+ styleConverter = javafx.css.converter.EffectConverter.getInstance();
+ break;
+ case "javafx.css.converter.EffectConverter$DropShadowConverter" :
+ styleConverter = javafx.css.converter.EffectConverter.DropShadowConverter.getInstance();
+ break;
+ case "javafx.css.converter.EffectConverter$InnerShadowConverter" :
+ styleConverter = javafx.css.converter.EffectConverter.InnerShadowConverter.getInstance();
+ break;
+ case "javafx.css.converter.FontConverter" :
+ styleConverter = javafx.css.converter.FontConverter.getInstance();
+ break;
+ case "javafx.css.converter.FontConverter$FontStyleConverter" :
+ case "javafx.css.converter.FontConverter$StyleConverter" :
+ styleConverter = javafx.css.converter.FontConverter.FontStyleConverter.getInstance();
+ break;
+ case "javafx.css.converter.FontConverter$FontWeightConverter" :
+ case "javafx.css.converter.FontConverter$WeightConverter" :
+ styleConverter = javafx.css.converter.FontConverter.FontWeightConverter.getInstance();
+ break;
+ case "javafx.css.converter.FontConverter$FontSizeConverter" :
+ case "javafx.css.converter.FontConverter$SizeConverter" :
+ styleConverter = javafx.css.converter.FontConverter.FontSizeConverter.getInstance();
+ break;
+
+ case "javafx.css.converter.InsetsConverter" :
+ styleConverter = javafx.css.converter.InsetsConverter.getInstance();
+ break;
+ case "javafx.css.converter.InsetsConverter$SequenceConverter" :
+ styleConverter = javafx.css.converter.InsetsConverter.SequenceConverter.getInstance();
+ break;
+
+ case "javafx.css.converter.PaintConverter" :
+ styleConverter = javafx.css.converter.PaintConverter.getInstance();
+ break;
+ case "javafx.css.converter.PaintConverter$SequenceConverter" :
+ styleConverter = javafx.css.converter.PaintConverter.SequenceConverter.getInstance();
+ break;
+ case "javafx.css.converter.PaintConverter$LinearGradientConverter" :
+ styleConverter = javafx.css.converter.PaintConverter.LinearGradientConverter.getInstance();
+ break;
+ case "javafx.css.converter.PaintConverter$RadialGradientConverter" :
+ styleConverter = javafx.css.converter.PaintConverter.RadialGradientConverter.getInstance();
+ break;
+
+ case "javafx.css.converter.SizeConverter" :
+ styleConverter = javafx.css.converter.SizeConverter.getInstance();
+ break;
+ case "javafx.css.converter.SizeConverter$SequenceConverter" :
+ styleConverter = javafx.css.converter.SizeConverter.SequenceConverter.getInstance();
+ break;
+
+ case "javafx.css.converter.StringConverter" :
+ styleConverter = javafx.css.converter.StringConverter.getInstance();
+ break;
+ case "javafx.css.converter.StringConverter$SequenceConverter" :
+ styleConverter = javafx.css.converter.StringConverter.SequenceConverter.getInstance();
+ break;
+ case "javafx.css.converter.URLConverter" :
+ styleConverter = javafx.css.converter.URLConverter.getInstance();
+ break;
+ case "javafx.css.converter.URLConverter$SequenceConverter" :
+ styleConverter = javafx.css.converter.URLConverter.SequenceConverter.getInstance();
+ break;
+
+ // Region stuff - including 2.x class names
+ case "com.sun.javafx.scene.layout.region.BackgroundPositionConverter" :
+ case "com.sun.javafx.scene.layout.region.BackgroundImage$BackgroundPositionConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BackgroundPositionConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.BackgroundSizeConverter" :
+ case "com.sun.javafx.scene.layout.region.BackgroundImage$BackgroundSizeConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BackgroundSizeConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.BorderImageSliceConverter" :
+ case "com.sun.javafx.scene.layout.region.BorderImage$SliceConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BorderImageSliceConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.BorderImageWidthConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BorderImageWidthConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.BorderImageWidthsSequenceConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BorderImageWidthsSequenceConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.BorderStrokeStyleSequenceConverter" :
+ case "com.sun.javafx.scene.layout.region.StrokeBorder$BorderStyleSequenceConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BorderStrokeStyleSequenceConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.BorderStyleConverter" :
+ case "com.sun.javafx.scene.layout.region.StrokeBorder$BorderStyleConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.BorderStyleConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.LayeredBackgroundPositionConverter" :
+ case "com.sun.javafx.scene.layout.region.BackgroundImage$LayeredBackgroundPositionConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.LayeredBackgroundPositionConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.LayeredBackgroundSizeConverter" :
+ case "com.sun.javafx.scene.layout.region.BackgroundImage$LayeredBackgroundSizeConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.LayeredBackgroundSizeConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.LayeredBorderPaintConverter" :
+ case "com.sun.javafx.scene.layout.region.StrokeBorder$LayeredBorderPaintConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.LayeredBorderPaintConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.LayeredBorderStyleConverter" :
+ case "com.sun.javafx.scene.layout.region.StrokeBorder$LayeredBorderStyleConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.LayeredBorderStyleConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.RepeatStructConverter" :
+ case "com.sun.javafx.scene.layout.region.BackgroundImage$BackgroundRepeatConverter" :
+ case "com.sun.javafx.scene.layout.region.BorderImage$RepeatConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.RepeatStructConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.SliceSequenceConverter" :
+ case "com.sun.javafx.scene.layout.region.BorderImage$SliceSequenceConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.SliceSequenceConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.StrokeBorderPaintConverter" :
+ case "com.sun.javafx.scene.layout.region.StrokeBorder$BorderPaintConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.StrokeBorderPaintConverter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.Margins$Converter" :
+ styleConverter = com.sun.javafx.scene.layout.region.Margins.Converter.getInstance();
+ break;
+ case "com.sun.javafx.scene.layout.region.Margins$SequenceConverter" :
+ styleConverter = com.sun.javafx.scene.layout.region.Margins.SequenceConverter.getInstance();
+ break;
+ case "javafx.scene.layout.CornerRadiiConverter" : // Fix for RT-39665
+ case "com.sun.javafx.scene.layout.region.CornerRadiiConverter" :
+ styleConverter = CornerRadiiConverter.getInstance();
+ break;
+
+ // parser stuff
+ case "javafx.css.converter.DeriveColorConverter":
+ case "com.sun.javafx.css.parser.DeriveColorConverter" :
+ styleConverter = DeriveColorConverter.getInstance();
+ break;
+ case "javafx.css.converter.DeriveSizeConverter":
+ case "com.sun.javafx.css.parser.DeriveSizeConverter" :
+ styleConverter = DeriveSizeConverter.getInstance();
+ break;
+ case "javafx.css.converter.LadderConverter":
+ case "com.sun.javafx.css.parser.LadderConverter" :
+ styleConverter = LadderConverter.getInstance();
+ break;
+ case "javafx.css.converter.StopConverter":
+ case "com.sun.javafx.css.parser.StopConverter" :
+ styleConverter = StopConverter.getInstance();
+ break;
+
+ default :
+ final PlatformLogger logger = Logging.getCSSLogger();
+ if (logger.isLoggable(Level.SEVERE)) {
+ logger.severe("StyleConverter : converter Class is null for : "+converterClass);
+ }
+ break;
+ }
+
+ return styleConverter;
+ }
+
+
+ /**
+ *
+ * @since 9
+ */
+ public static class StringStore {
+ private final Map<String,Integer> stringMap = new HashMap<String,Integer>();
+ public final List<String> strings = new ArrayList<String>();
+
+ public int addString(String s) {
+ Integer index = stringMap.get(s);
+ if (index == null) {
+ index = strings.size();
+ strings.add(s);
+ stringMap.put(s,index);
+ }
+ return index;
+ }
+
+ public void writeBinary(DataOutputStream os) throws IOException {
+ os.writeShort(strings.size());
+ if (stringMap.containsKey(null)) {
+ Integer index = stringMap.get(null);
+ os.writeShort(index);
+ } else {
+ os.writeShort(-1);
+ }
+ for (int n=0; n<strings.size(); n++) {
+ String s = strings.get(n);
+ if (s == null) continue;
+ os.writeUTF(s);
+ }
+ }
+
+ // TODO: this isn't parallel with writeBinary
+ public static String[] readBinary(DataInputStream is) throws IOException {
+ int nStrings = is.readShort();
+ int nullIndex = is.readShort();
+ String[] strings = new String[nStrings];
+ java.util.Arrays.fill(strings, null);
+ for (int n=0; n<nStrings; n++) {
+ if (n == nullIndex) continue;
+ strings[n] = is.readUTF();
+ }
+ return strings;
+ }
+ }
}