JavaFX 2.2 内置控件没有默认样式

JavaFX 2.2 built-in controls have no default style

虽然 CSS 样式教程提到了默认样式 sheet (caspian.css) 和内置控件的默认 classes(例如 .line 表示 Line) ,我的控件似乎缺少两者(由调试器检查)。

因此,如果我没有明确设置它们的 class,它们不会对额外的自定义 CSS 做出反应,这很烦人并且破坏了全局 CSS 样式的全部意义.

对于可能导致此类行为的任何想法,我将不胜感激。

在JavaFX中,支持三个CSS选择器,类似于标准CSS中的类型选择器、Class选择器和ID选择器。重要的是要小心 "class" 这个词,它在 Java 世界和 CSS 世界中有不同的含义:Java class 是CSS类型; CSS class 通过名为 styleClass.

的 属性 在节点上设置

类型选择器由接口Styleable中声明的方法getTypeSelector的调用结果决定。 Node实现了这个接口,实现了getTypeSelector到return

getClass().getName() without the package name

因此 任何 Node 可以通过指定其简单的 class 名称来设置样式:

Label {
    -fx-text-fill: green ;
}
Line {
    -fx-stroke: red ;
}

等等

CSSclasses是由Styleable中的getStyleClass()方法决定的,return是一个字符串列表。 (请注意,节点可能有多个样式 classes,虽然我一直不明白为什么这是 List 而不是 Set。)默认情况下,此列表为空,但 Control subclasses 通过他们的默认皮肤将此值设置为 class 名称的 "css-ized" 版本(Button 变为 buttonComboBox 变成 combo-box,等等)。于是

.label {
    -fx-text-fill: green ;
}

有效,但是

.line {
    -fx-stroke: red ;
}

如果没有预先设置样式就不起作用 class:

Line line = new Line();
line.getStyleClass().add("line");

最后,ID 选择器通过在节点上指定一个 id 来工作。 Ids 在场景图中的所有节点中都是唯一的。所以你可以做

Line line = new Line();
line.setId("my-line");

#my-line {
    -fx-stroke: red ;
}

因此在您的示例中,默认情况下未设置样式 class(Line 不是 Control 子 class)。您必须设置它 "by hand",或使用类型选择器。

最后一点:你提到你的行 "lacked caspian.css"。我不太确定这是什么意思(因为 Lines 根本没有被默认样式表设置样式),但是默认样式表仅在第一次实例化 Control 时加载。这是为了增强不使用控件的场景图的性能(因此无论如何都不会从默认样式表中受益)。