如何解析/映射JavaFX的CSS文件以检索其属性和值?

 2023-02-16    485  

问题描述

我的应用程序允许用户使用自定义CSS主题来样式接口.我有几个预先构建的”主题”可供选择,这很简单,只有3个属性.

样本CSS:

如何解析/映射JavaFX的CSS文件以检索其属性和值?

.root{
    -fx-background: #325c81;
    -fx-default-button: #77a3ca;
    -fx-base: #a7c4dd;
}

该应用程序具有3 ColorPicker控制,需要允许用户为每个属性选择颜色并保存回CSS文件.

我实际编写CSS文件没有问题,但是我找不到解析.css文件的方法,以便用.css file的值设置ColorPicker控件的值.

基本程序流

1)用户从ComboBox中选择一个预制主题:

cboPresetTheme.valueProperty().addListener((observable, priorTheme, newTheme) -> {
                Utility.applyTheme(cboPresetTheme.getScene(), newTheme);
            });

2)关联.css文件已加载并应用于当前Scene:

public static void applyTheme(Scene scene, Theme theme) {
    scene.getStylesheets().clear();

    File css = new File("themes/" + theme.getFileName());
    File fontFile = new File("themes/Font.css");

    scene.getStylesheets().addAll(
            css.toURI().toString(),
            fontFile.toURI().toString());
}

3)3 ColorPicker对控件的更新,并使用来自Applied StyleSheet的值:

.

cpBackground.setValue(Color.valueOf(cssFileBackground));
cpBase.setValue(Color.valueOf(cssFileBase));
cpDefaultButton.setValue(Color.valueOf(cssFileDefaultButton));

虽然步骤1和2没有问题,但我不知道如何处理步骤3.

我看过其他CSS解析器库(谢谢Google),但它们似乎更适合CSS,并且不支持FX属性. stackexchange问​​题似乎在问相同的问题,但从未成功回答.

一个答案建议使用 css parser 实现这一目标(还有什么超出我当前的理解水平),我不知道从哪里开始.

我知道目前可能没有标准API来完成此操作,但是我希望那里可能有一个简单的库或解决方案,我找不到.

推荐答案

有几种方法可以解决CSS声明为颜色的转换.

样式辅助节点

这很简单,但有效:想法是,您可以使用相同CSS的节点的背景颜色来样式,然后用该颜色设置colorPicker值.

在这种情况下,您唯一需要考虑的事情是添加到场景中的节点仅 .

因此,您必须将节点添加到场景中.添加具有0x0大小的节点不会引起任何问题,但也许您不希望它在那里,因此您可以使用辅助场景.

public class CSSParsingApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        ColorPicker cpBackground = new ColorPicker(retrieveColor("value1"));
        ColorPicker cpBase = new ColorPicker(retrieveColor("value2"));
        ColorPicker cpDefaultButton = new ColorPicker(retrieveColor("value3"));

        VBox root = new VBox(10, cpBackground, cpDefaultButton, cpBase);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root, 300, 250);
        scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Color retrieveColor(String value) {
        Pane pane = new Pane();
        pane.getStyleClass().add(value);

        Scene sceneAux = new Scene(pane);
        sceneAux.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
        pane.applyCss();
        return (Color) pane.getBackground().getFills().get(0).getFill();
    }

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

}

其中style.css是:

.root {
    -fx-background: #325c81;
    -fx-default-button: #77a3ca;
    -fx-base: #a7c4dd;
}
.value1 {
    -fx-background-color: -fx-background;
}
.value2 {
    -fx-background-color: -fx-default-button;
}
.value3 {
    -fx-background-color: -fx-base;
}

使用Stylable Properties

找到类似,更优雅的解决方案在这里 .它使用StylableProperties创建一个节点,您可以使用自定义-named-color属性进行样式,然后将此helper节点添加到主场景中.

基本上,它与上面的想法相同,可能更干净,因为您不需要修改CSS文件.

使用CssToColorHelper,您的代码将如下:

public class CSSParsingApp extends Application {

    private CssToColorHelper helper = new CssToColorHelper();

    @Override
    public void start(Stage primaryStage) {
        ColorPicker cpBackground = new ColorPicker();
        ColorPicker cpBase = new ColorPicker();
        ColorPicker cpDefaultButton = new ColorPicker();  

        VBox root = new VBox(10, cpBackground, cpDefaultButton, cpBase, helper);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root, 300, 250);
        scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());

        cpBackground.setValue(getNamedColor("-fx-background"));
        cpDefaultButton.setValue(getNamedColor("-fx-default-button"));
        cpBase.setValue(getNamedColor("-fx-base"));

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

        return helper.getNamedColor();      
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

其中style.css是您的CSS文件:

.root {
    -fx-background: #325c81;
    -fx-default-button: #77a3ca;
    -fx-base: #a7c4dd;
}

使用javafx cssparser

如果您正在寻找CSSPARSER,为什么不使用Javafx中包含的cssparser,实际上使用的javafx中的型号?

?

它在com.sun.javafx.css.parser.CSSParser下/java/jdk9/jfxdocs/javafx/css/cssparser.html” rel =” noreferrer”> javafx 9 .

使用它,您可以解析CSS文件并轻松检索任何解析值.

public class CSSParsingApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        ColorPicker cpBackground = new ColorPicker();
        ColorPicker cpBase = new ColorPicker();
        ColorPicker cpDefaultButton = new ColorPicker();  

        VBox root = new VBox(10, cpBackground, cpDefaultButton, cpBase);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root, 300, 250);
        scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());

        cpBackground.setValue(parseColor("-fx-background"));
        cpDefaultButton.setValue(parseColor("-fx-default-button"));
        cpBase.setValue(parseColor("-fx-base"));

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Color parseColor(String property) {
        CSSParser parser = new CSSParser();
        try {
            Stylesheet css = parser.parse(getClass().getResource("style.css").toURI().toURL());
            final Rule rootRule = css.getRules().get(0); // .root
            return (Color) rootRule.getDeclarations().stream()
                .filter(d -> d.getProperty().equals(property))
                .findFirst()
                .map(d -> ColorConverter.getInstance().convert(d.getParsedValue(), null))
                .get();
        } catch (URISyntaxException | IOException ex) { }
        return Color.WHITE;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

其中style.css是您的CSS文件:

.root {
    -fx-background: #325c81;
    -fx-default-button: #77a3ca;
    -fx-base: #a7c4dd;
}

以上所述是小编给大家介绍的如何解析/映射JavaFX的CSS文件以检索其属性和值?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/34025.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。