Convert color from CSS to javafx color object

2019-04-12 01:18发布

问题:

I am wondering if it is possible to convert a color defined in CSS like

.root {
    my-blue: rgb(50,100,200); 
}

Into a Color Object in JavaFX.

For example with the CSS definition I could use setStyle on a Node to set its Color:

label1.setStyle("-fx-background-color: my-blue");

But is it possible to do something like:

Color blue = my-blue;   // is this possible somehow?

Background background = new Background(new BackgroundFill(blue, null, null));
label1.setBackground(background);

回答1:

I was able to do it by using StyleableProperties like this:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javafx.beans.property.ObjectProperty;
import javafx.beans.value.WritableValue;
import javafx.css.CssMetaData;
import javafx.css.Styleable;
import javafx.css.StyleableObjectProperty;
import javafx.css.StyleableProperty;
import javafx.scene.Parent;
import javafx.scene.paint.Color;

import com.sun.javafx.css.converters.ColorConverter;


public class CssToColorHelper extends Parent{
  public static final Color DEFAULT_NAMED_COLOR = null;

  private ObjectProperty<Color> namedColor;

  public ObjectProperty<Color> namedColorProperty() {
    if(namedColor == null) {
      namedColor = new StyleableObjectProperty<Color>(DEFAULT_NAMED_COLOR) {

        @Override
        protected void invalidated() {
          super.invalidated();
        }

        @Override
        public CssMetaData<? extends Styleable, Color> getCssMetaData() {
          return StyleableProperties.NAMED_COLOR;
        }

        @Override
        public Object getBean() {
          return CssToColorHelper.this;
        }

        @Override
        public String getName() {
          return "namedColor";
        }
      };
    }
    return namedColor;
  }

  public Color getNamedColor() {
    return namedColorProperty().get();
  }

  public CssToColorHelper() {
    setFocusTraversable(false);
    getStyleClass().add("css-to-color-helper");
  }

  private static class StyleableProperties {
    private static final CssMetaData<CssToColorHelper, Color> NAMED_COLOR =
        new CssMetaData<CssToColorHelper, Color>("-named-color", ColorConverter.getInstance(),
            DEFAULT_NAMED_COLOR) {

          @Override
          public boolean isSettable(CssToColorHelper n) {
            return n.namedColor == null || !n.namedColor.isBound();
          }

          @Override
          public StyleableProperty<Color> getStyleableProperty(CssToColorHelper n) {
            return (StyleableProperty<Color>) (WritableValue<Color>) n.namedColorProperty();
          }

      };

      private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
      static {
        final List<CssMetaData<? extends Styleable, ?>> styleables =
            new ArrayList<>(Parent.getClassCssMetaData());
        styleables.add(NAMED_COLOR);
        STYLEABLES = Collections.unmodifiableList(styleables);
      }
    }

  @Override
  public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
    return StyleableProperties.STYLEABLES;
  }
}

The main class of my SSCCE looks like this:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class TestMain extends Application {
    private CssToColorHelper helper = new CssToColorHelper();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
      Scene scene = new Scene(new Group(), 450, 250);

      scene.getStylesheets().add("colors.css");

      TextField textfield = new TextField();      

      Group root = (Group) scene.getRoot();
      root.getChildren().add(textfield);
      root.getChildren().add(helper);
      stage.setScene(scene);       

      Color blue = getNamedColor("my-blue");

      Background bgf = new Background(new BackgroundFill(blue, null, null));
      textfield.setBackground(bgf);  

      stage.show();        
    }  

    Color getNamedColor(String name) {
      helper.setStyle("-named-color: " + name + ";");
      helper.applyCss();

      return helper.getNamedColor();      
    }
}

And the CSS-file looks like this:

.root {
    my-blue: rgb(50,100,200);
}

.css-to-color-helper {    
}


回答2:

Is that was you are looking for?

final Color blue = Color.rgb(50, 100, 200);

Background bg = new Background(new BackgroundFill(blue, null, null));
label1.setBackground(bg);