JavaFx:如何为节点的给定样式 class 获取相应的样式表?
JavaFx: How to get the corresponding stylesheet for a given style class of a Node?
我能够使用
检索JavaFx节点"node"的样式class(es)
List<String> styleClasses = node.getStyleClass();
例如,这给了我样式 class "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(getCssMetaData()
是在版本 8 中引入的),因此您希望参考 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: []}]}
其中,如果你深入研究一下,你会看到包含
subProperties: [CSSProperty {property: -fx-background-color, converter: Paint.SequenceConverter, initalValue: [Ljavafx.scene.paint.Paint;@737bd041, inherits: false, subProperties: []}, ...]
所以 -fx-background-color
就在那里。
据我所知,它的工作方式是 CssMetaData
对象描述了如何将 CSS 映射到实际的 JavaFX 属性([的实例=22=],它是 WritableValue
的子类。因此,如果你仔细研究这个,你应该能够弄清楚 -fx-region-background
映射到 Region.backgroundProperty()
,而 -fx-background-color
映射到Region.getBackground().getFills()
的每个元素的fill
属性。代码片段
Background bg = node.getBackground();
bg.getFills().forEach(fill -> System.out.println(fill.getFill()));
产生输出
0xf4f4f4ff
我认为这是 modena.css
中为 chart-plot-background
定义的背景色。
因此,如果你想自动执行此操作,虽然有可能,但似乎非常棘手。您需要考虑 "nested" 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);
}
}
我能够使用
检索JavaFx节点"node"的样式class(es)List<String> styleClasses = node.getStyleClass();
例如,这给了我样式 class "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(getCssMetaData()
是在版本 8 中引入的),因此您希望参考 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: []}]}
其中,如果你深入研究一下,你会看到包含
subProperties: [CSSProperty {property: -fx-background-color, converter: Paint.SequenceConverter, initalValue: [Ljavafx.scene.paint.Paint;@737bd041, inherits: false, subProperties: []}, ...]
所以 -fx-background-color
就在那里。
据我所知,它的工作方式是 CssMetaData
对象描述了如何将 CSS 映射到实际的 JavaFX 属性([的实例=22=],它是 WritableValue
的子类。因此,如果你仔细研究这个,你应该能够弄清楚 -fx-region-background
映射到 Region.backgroundProperty()
,而 -fx-background-color
映射到Region.getBackground().getFills()
的每个元素的fill
属性。代码片段
Background bg = node.getBackground();
bg.getFills().forEach(fill -> System.out.println(fill.getFill()));
产生输出
0xf4f4f4ff
我认为这是 modena.css
中为 chart-plot-background
定义的背景色。
因此,如果你想自动执行此操作,虽然有可能,但似乎非常棘手。您需要考虑 "nested" 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);
}
}