JavaFx:如何为节点的给定样式类获取相应的样式表?

Ste*_*fan 5 css javafx stylesheet

我能够检索 JavaFx 节点“节点”的样式类

List<String> styleClasses = node.getStyleClass();
Run Code Online (Sandbox Code Playgroud)

例如,这给了我样式类“chart-plot-background”。

如何从节点检索相应的当前活动样式表条目?

Caspian.css 文件包含条目

.chart-plot-background {
-fx-background-color: #f5f5f5;
}
Run Code Online (Sandbox Code Playgroud)

我希望能够至少使用以下代码片段从节点中检索此信息:

一种。

Style style = node.getStyle();
//is empty
Run Code Online (Sandbox Code Playgroud)

B.

Parent parent = (Parent) node;
List<String> styleSheets = parent.getStyleSheets();
//... loop through the list and search for the entry...
//however, the list is empty
Run Code Online (Sandbox Code Playgroud)

C。

List<CssMetaData<? extends Styleable, ?>> cssMetaDataList = node.getCssMetaData();
//... loop through the list and search for the entry...
//however, the property "-fx-background-color" is null
Run Code Online (Sandbox Code Playgroud)

相关老文章:

解析节点的 CSS 属性

指向错误票

http://bugs.openjdk.java.net/browse/JDK-8091202

动机

我想编写一个从 JavaFx 图表到可缩放矢量图形 (*.svg) 文件的转换器。为此,我需要每个节点的活动属性,例如填充颜色和笔触宽度。

Jam*_*s_D 4

首先请注意:JavaFX 8modena.css默认使用,而不是caspian.css. 由于您使用的是 JavaFX 8(getCssMetaData()在版本 8 中引入),因此您需要参考modena.css,除非您使用系统属性开关来使用旧的用户代理样式表。

这只是部分答案;深入研究如何做到这一点将花费比我更多的时间。不过,这应该可以帮助您开始。如果有人已经完成了解决这个问题的工作,他们也许能够提供更完整的答案。

-fx-background-color实际上是 的子属性-fx-region-background,正如 的CSS 参考Region中所暗示的那样。代码片段

    Region node = (Region)root.lookup(".chart-plot-background");
    node.getCssMetaData().stream().filter(p -> p.getProperty().equals("-fx-region-background"))
        .findFirst()
        .ifPresent(System.out::println);
Run Code Online (Sandbox Code Playgroud)

产生输出

CSSProperty {属性:-fx-region-background,转换器:javafx.scene.layout.BackgroundConverter@6f457c5c,initalValue:null,继承:false,subProperty:[CSSProperty {属性:-fx-background-color,转换器:Paint.SequenceConverter , initalValue: [Ljavafx.scene.paint.Paint;@737bd041, 继承: false, subProperties: []}, CSSProperty {属性: -fx-background-insets, 转换器: InsetsSequenceConverter, initalValue: [Ljavafx.geometry.Insets;@ 22e4912,继承:false,subProperties:[]},CSSProperty {属性:-fx-background-radius,转换器:javafx.scene.layout.CornerRadiiConverter@3d63caf3,initalValue:[Ljavafx.scene.layout.CornerRadii;@7980e69f,继承: false, subProperties: []}, CSSProperty {属性: -fx-background-image, 转换器: URLSeqType, initalValue: null, 继承: false, subProperties: []}, CSSProperty {属性: -fx-background-repeat, 转换器:RepeatStructConverter, initalValue: [Lcom.sun.javafx.scene.layout.region.RepeatStruct;@54d4d836, 继承: false, subProperties: []}, CSSProperty {属性: -fx-background-position, 转换器: LayeredBackgroundPositionConverter, initalValue: [Ljavafx.scene.layout.BackgroundPosition;@24c26d67,继承:false,子属性:[]},CSSProperty {属性:-fx-background-size,转换器:com.sun.javafx.scene.layout.region.LayeredBackgroundSizeConverter@7550f5e , initalValue: [Ljavafx.scene.layout.BackgroundSize;@791fb535, 继承: false, subProperties: []}]}

如果你深入研究一下,你会发现其中包含

子属性:[CSSProperty {属性:-fx-background-color,转换器:Paint.SequenceConverter,initalValue:[Ljavafx.scene.paint.Paint;@737bd041,继承:false,子属性:[]},...]

所以它就-fx-background-color在那里。

据我所知,它的工作方式是,对象CssMetaData描述如何将 CSS 映射到实际的 JavaFX 属性( 的实例StyleableProperty,它是 的子类WritableValue。因此,如果您深入研究这一点,您应该能够找出-fx-region-background映射到Region.backgroundProperty(),并-fx-background-color映射到fill的每个元素的属性Region.getBackground().getFills()。代码片段

    Background bg = node.getBackground();
    bg.getFills().forEach(fill -> System.out.println(fill.getFill()));
Run Code Online (Sandbox Code Playgroud)

产生输出

0xf4f4f4ff

我相信这是modena.csschart-plot-background.

因此,如果你想实现自动化,这似乎相当棘手,尽管这是可能的。您需要考虑“嵌套”CSS 元数据,您可以通过getSubProperties(). 然后,您应该能够调用getStyleableProperty().getValue(), 并(可能通过反射)深入研究结果对象以获取“subProperties”设置的值。

祝你好运...

我用于测试的完整代码:

import java.util.Random;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.Background;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;


public class CssPropertyLookupTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        LineChart<Number, Number> chart = new LineChart<>(new NumberAxis(), new NumberAxis());
        chart.setAnimated(false);
        Random rng = new Random();

        Series<Number, Number> series = new Series<>();
        for (int x = 1; x <= 10; x++) {
            Data<Number, Number> data = new Data<>(x, rng.nextDouble());
            series.getData().add(data);
        }
        chart.getData().add(series);

        Rectangle rect = new Rectangle(400, 20);

        BorderPane root = new BorderPane(chart, null, null, rect, null);
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();

        Region node = (Region)root.lookup(".chart-plot-background");
        node.getCssMetaData().stream()
            .filter(p -> p.getProperty().equals("-fx-region-background"))
            .findFirst()
            .ifPresent(System.out::println);

        Background bg = node.getBackground();
        bg.getFills().forEach(fill -> System.out.println(fill.getFill()));
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)