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 }