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

标签 css javafx stylesheet

我可以通过以下方式检索 JavaFx 节点“节点”的样式类

List<String> styleClasses = node.getStyleClass();

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

如何从节点中检索相应的当前事件样式表条目?

Caspian.css 文件包含条目

.chart-plot-background {
-fx-background-color: #f5f5f5;
}

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

A.

Style style = node.getStyle();
//is empty

B.

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

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

相关旧文:

Resolving CSS property for node

指向错误单

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

动机

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

最佳答案

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

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

-fx-background-color 实际上是 -fx-region-background 的子属性,正如 CSS reference for 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);

产生输出

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

which, if you dig into a little, you will see contains

subProperties: [CSSProperty {property: -fx-background-color, converter: Paint.SequenceConverter, initalValue: [Ljavafx.scene.paint.Paint;@737bd041, inherits: false, subProperties: []}, ...]

So the -fx-background-color is in there.

The way this works, to the best of my knowledge, is that the CssMetaData objects describe how to map the CSS into an actual JavaFX property (an instance of StyleableProperty, which is a subclass of WritableValue. So if you dig through this, you should be able to figure out that -fx-region-background maps to Region.backgroundProperty(), and -fx-background-color maps to the fill property of each element of Region.getBackground().getFills(). The code snippet

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

产生输出

0xf4f4f4ff

which I believe is the background color defined in modena.css for the chart-plot-background.

So if you want to automate this, it seems pretty tricky, albeit possible. You'll need to account for "nested" css meta data, which you can access via getSubProperties(). You should then be able to call getStyleableProperty().getValue(), and (possibly by reflection) dig into the resulting object to get the values set by the "subProperties".

Good luck...

Complete code I used for testing:

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);
    }
}

关于css - JavaFx:如何为节点的给定样式类获取相应的样式表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32160980/

相关文章:

javascript - 按钮禁用 - 如何改变外观

jquery - 无限滚动 jQuery 插件 : how to fix loading graphic from "animating" left to center of page?

div的CSS3 flex 切口?

javafx - 为什么 TableView 的更改监听器对 JavaFX8 中的 ObjectProperty<T> 与 TProperty 列给出不同的结果?

java - 在 JVM 上设置默认参数

css - 如何在 Wordpress 中编辑 CU3ER 字幕的样式?

html - 如何制作响应式内容

JavaFX 绑定(bind)布局Y : A bound value cannot be set

image - Chrome 27 不再加载背景图片

css - 将 css 分配给特定元素