1 package test.javafx.css;
   2 
   3 import com.sun.javafx.property.PropertyReference;
   4 import javafx.scene.paint.LinearGradient;
   5 import javafx.beans.property.ReadOnlyProperty;
   6 import javafx.beans.value.ObservableValue;
   7 import javafx.geometry.Insets;
   8 import javafx.geometry.Pos;
   9 import javafx.scene.Group;
  10 import javafx.scene.Scene;
  11 import javafx.scene.effect.BlurType;
  12 import javafx.scene.effect.Effect;
  13 import javafx.scene.effect.InnerShadow;
  14 import javafx.scene.paint.Color;
  15 import javafx.scene.paint.CycleMethod;
  16 import javafx.scene.paint.Paint;
  17 import javafx.scene.paint.Stop;
  18 import javafx.scene.text.Font;
  19 import javafx.util.Duration;
  20 import org.hamcrest.BaseMatcher;
  21 import org.hamcrest.CoreMatchers;
  22 import org.hamcrest.Description;
  23 import org.hamcrest.Matcher;
  24 import org.junit.Before;
  25 import org.junit.Test;
  26 import org.junit.runner.RunWith;
  27 import org.junit.runners.Parameterized;
  28 
  29 import java.util.Arrays;
  30 import java.util.Collection;
  31 import java.util.List;
  32 import javafx.css.CssMetaData;
  33 import javafx.css.Styleable;
  34 import javafx.css.StyleableProperty;
  35 import javafx.css.StyleablePropertyFactory;
  36 
  37 import static org.junit.Assert.*;
  38 
  39 @RunWith(Parameterized.class)
  40 public class StyleablePropertyFactoryTest {
  41 
  42     private static class Data<T> {
  43 
  44         final PropertyReference propertyReference;
  45         final String style;
  46         final T value;
  47         final Matcher<T> matcher;
  48 
  49         Data(String name, String style, T value) {
  50             this(name,style,value,CoreMatchers.equalTo(value));
  51         }
  52 
  53         Data(String name, String style, T value, Matcher<T> matcher) {
  54             this.propertyReference = new PropertyReference(MyStyleable.class, name);
  55             this.style = style;
  56             this.value = value;
  57             this.matcher = matcher;
  58         }
  59     }
  60 
  61     private final Data data;
  62 
  63     public StyleablePropertyFactoryTest(Data data) {
  64         this.data = data;
  65     }
  66 
  67     @Parameterized.Parameters
  68     public static Collection<Data[]> data() {
  69 
  70         return Arrays.asList(new Data[][]{
  71                 {new Data("myBoolean", "-my-boolean: true;", Boolean.TRUE)},
  72                 {new Data("myColor", "-my-color: red;", Color.RED)},
  73                 {new Data("myDuration", "-my-duration: 30ms;", Duration.millis(30))},
  74                 {new Data("myEffect", "-my-effect: innershadow(gaussian, red, 10, .5, 1, 1);",
  75                         new InnerShadow(BlurType.GAUSSIAN, Color.RED, 10, .5, 1, 1),
  76                         new BaseMatcher<InnerShadow>() {
  77                             @Override
  78                             public boolean matches(Object o) {
  79                                 InnerShadow actual = (InnerShadow)o;
  80                                 return (actual.getBlurType() == BlurType.GAUSSIAN &&
  81                                         actual.getColor().equals(Color.RED) &&
  82                                         Double.compare(actual.getRadius(),10d) ==  0 &&
  83                                         Double.compare(actual.getChoke(),.5d) ==  0 &&
  84                                         Double.compare(actual.getOffsetX(),1d) ==  0 &&
  85                                         Double.compare(actual.getOffsetY(),1d) ==  0);
  86                             }
  87                             @Override
  88                             public void describeTo(Description description) {
  89                                 description.appendText("InnerShadow(BlurType.GAUSSIAN, Color.RED, 10, .5, 1, 1)");
  90                             }
  91                         })
  92                 },
  93                 {new Data("myPos", "-my-pos: bottom-right;", Pos.BOTTOM_RIGHT)},
  94                 {new Data("myFont", "-my-font: 18 system;", Font.font("system", 18))},
  95                 {new Data("myInsets", "-my-insets: 1 2 3 4;", new Insets(1,2,3,4))},
  96                 {new Data("myInsets", "-my-insets: 5;", new Insets(5,5,5,5))},
  97                 {new Data("myInsets", "-my-insets: 7 8;", new Insets(7,8,7,8))},
  98                 {new Data("myInsets", "-my-insets: 9 10 11;", new Insets(9,10,11,10))},
  99                 {new Data("myPaint", "-my-paint: linear-gradient(from 0% 0% to 100% 100%, red 0%, black 100%);",
 100                         new LinearGradient(0,0,1,1,true, CycleMethod.NO_CYCLE,new Stop[] { new Stop(0,Color.RED), new Stop(1,Color.BLACK) }))
 101                 },
 102                 {new Data("myNumber", "-my-number: 2em;", Font.getDefault().getSize()*2)},
 103                 {new Data("myString", "-my-string: \"yaba daba do\";", "yaba daba do")},
 104                 {new Data("myUrl", "-my-url: url('http://www.oracle.com');", "http://www.oracle.com")}
 105         });
 106 
 107     }
 108 
 109     @Test
 110     public void theTest() {
 111         MyStyleable styleable = new MyStyleable();
 112         styleable.setStyle(data.style);
 113 
 114         Scene scene = new Scene(styleable);
 115         styleable.applyCss();
 116 
 117         ReadOnlyProperty prop = data.propertyReference.getProperty(styleable);
 118         assertThat(prop.getValue(), data.matcher);
 119     }
 120 
 121     public static class MyStyleable extends Group {
 122 
 123         public MyStyleable() {
 124         }
 125 
 126         private static final StyleablePropertyFactory fac = new StyleablePropertyFactory<>(null);
 127 
 128         public ObservableValue<Boolean> myBooleanProperty () { return (ObservableValue<Boolean>) myBoolean; }
 129         public Boolean getMyBoolean() { return myBoolean.getValue(); }
 130         public void setMyBoolean(Boolean value) { myBoolean.setValue(value); }
 131         private final StyleableProperty<Boolean> myBoolean = fac.createStyleableBooleanProperty(this, "myBoolean", "-my-boolean", s -> ((MyStyleable) s).myBoolean);
 132 
 133         public ObservableValue<Color> myColorProperty () { return (ObservableValue<Color>) myColor; }
 134         public Color getMyColor() { return myColor.getValue(); }
 135         public void setMyColor(Color value) { myColor.setValue(value); }
 136         private final StyleableProperty<Color> myColor = fac.createStyleableColorProperty(this, "myColor", "-my-color", s -> ((MyStyleable) s).myColor);
 137 
 138         public ObservableValue<Duration> myDurationProperty () { return (ObservableValue<Duration>) myDuration; }
 139         public Duration getMyDuration() { return myDuration.getValue(); }
 140         public void setMyDuration(Duration value) { myDuration.setValue(value); }
 141         private final StyleableProperty<Duration> myDuration = fac.createStyleableDurationProperty(this, "myDuration", "-my-duration", s -> ((MyStyleable) s).myDuration);
 142 
 143         public ObservableValue<Effect> myEffectProperty () { return (ObservableValue<Effect>) myEffect; }
 144         public Effect getMyEffect() { return myEffect.getValue(); }
 145         public void setMyEffect(Effect value) { myEffect.setValue(value); }
 146         private final StyleableProperty<Effect> myEffect = fac.createStyleableEffectProperty(this, "myEffect", "-my-effect", s -> ((MyStyleable) s).myEffect);
 147 
 148         public ObservableValue<Pos> myPosProperty () { return (ObservableValue<Pos>) myPos; }
 149         public Pos getMyPos() { return myPos.getValue(); }
 150         public void setMyPos(Pos value) { myPos.setValue(value); }
 151         private final StyleableProperty<Pos> myPos = fac.createStyleableEnumProperty(this, "myPos", "-my-pos", s -> ((MyStyleable) s).myPos, Pos.class);
 152 
 153         public ObservableValue<Font> myFontProperty () { return (ObservableValue<Font>) myFont; }
 154         public Font getMyFont() { return myFont.getValue(); }
 155         public void setMyFont(Font value) { myFont.setValue(value); }
 156         private final StyleableProperty<Font> myFont = fac.createStyleableFontProperty(this, "myFont", "-my-font", s -> ((MyStyleable) s).myFont);
 157 
 158         public ObservableValue<Insets> myInsetsProperty () { return (ObservableValue<Insets>) myInsets; }
 159         public Insets getMyInsets() { return myInsets.getValue(); }
 160         public void setMyInsets(Insets value) { myInsets.setValue(value); }
 161         private final StyleableProperty<Insets> myInsets = fac.createStyleableInsetsProperty(this, "myInsets", "-my-insets", s -> ((MyStyleable) s).myInsets);
 162 
 163         public ObservableValue<Paint> myPaintProperty () { return (ObservableValue<Paint>) myPaint; }
 164         public Paint getMyPaint() { return myPaint.getValue(); }
 165         public void setMyPaint(Paint value) { myPaint.setValue(value); }
 166         private final StyleableProperty<Paint> myPaint = fac.createStyleablePaintProperty(this, "myPaint", "-my-paint", s -> ((MyStyleable) s).myPaint);
 167 
 168         public ObservableValue<Double> myNumberProperty () { return (ObservableValue<Double>) myNumber; }
 169         public Double getMyNumber() { return myNumber.getValue().doubleValue(); }
 170         public void setMyNumber(Double value) { myNumber.setValue(value); }
 171         private final StyleableProperty<Number> myNumber = fac.createStyleableNumberProperty(this, "myNumber", "-my-number", s -> ((MyStyleable) s).myNumber);
 172 
 173         public ObservableValue<String> myStringProperty () { return (ObservableValue<String>) myString; }
 174         public String getMyString() { return myString.getValue(); }
 175         public void setMyString(String value) { myString.setValue(value); }
 176         private final StyleableProperty<String> myString = fac.createStyleableStringProperty(this, "myString", "-my-string", s -> ((MyStyleable) s).myString);
 177 
 178         public ObservableValue<String> myUrlProperty () { return (ObservableValue<String>) myUrl; }
 179         public String getMyUrl() { return myUrl.getValue(); }
 180         public void setMyUrl(String value) { myUrl.setValue(value); }
 181         private final StyleableProperty<String> myUrl = fac.createStyleableUrlProperty(this, "myUrl", "-my-url", s -> ((MyStyleable) s).myUrl);
 182 
 183         @Override
 184         public String getTypeSelector() {
 185             return "MyStyleable";
 186         }
 187 
 188         @Override
 189         public Styleable getStyleableParent() {
 190             return null;
 191         }
 192 
 193         @Override
 194         public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
 195             return fac.getCssMetaData();
 196         }
 197     }
 198 }