这个主题讲述了:怎样在JavaFX中使用CSS来给你的应用程序创建自定义的外观样式表包含了关于UI元素的外观样式定义。在JavaFX中使用CSS和在HTML使用css类似。JavaFX中的css是基于W3C css2.1版本,添加了一些目前CSS3.0的工作版本的一些内容和支持javafx特性的一些扩展功能。通过在Javafx中的使用css,可以改变你的UI外观,图37-1和图37-2显示了前后的变化。
图37-1 样式1
图37-2 样式2
JavaFX应用程序中默认的样式表是modena.css,这个文件可以在JavaFX运行时JAR文件jfxrt.jar中能够找到,它定义了根节点和UI控件的样式。jfxrt.jar存在于jdk的安装目录的\jre\lib\ext目录下。使用如下命令可以从这个jar文件中提取出modena.css:
jar xf jfxrt.jar com/sun/javafx/scene/control/skin/modena/modena.css |
图37-3显示了示例UI的默认样式的外观
图37-3 默认样式
创建样式表
你能够创建并添加自己的样式表来覆盖默认的样式。最典型的做法是,你可以创建以.css为扩展名的文件,然后把它们放到与JavaFX应用程序主类相同的目录下。
样式表controlStyle1.css提供了图37-1中的外观定义,样式表controlStyle2.css提供了图37-2中的外观定义。它们能够应用到Scene对象上,该对象的path代表样式表的路径,stylesheet代表样式表的名称。例如图37-2中的样式表的path和name是uicontrolcss/controlStyle2.css。
例子37-1 增加一个样式表
Scene scene = new Scene(new Group(), 500, 400); scene.getStylesheets().add("path/stylesheet.css"); |
定义样式
一个样式定义包含样式的名称(也叫选择器),一系列样式属性的规则集合。定义个规则用{}括起来。例子37-2定义两个一个名叫.custom-button的样式。
例子37-2 样式定义
.custom-button { -fx-font: 16px "Serif"; -fx-padding: 10; -fx-background-color: #CCFF99; } |
选择器
有多种类型的样式可以定义,每种类型的样式都有它自己对选择的约定。
样式类classes对应class的名字。按照惯例,样式class名包含一个或多个单词,中间用-连接,前面用.开头。
class选择器的例子:
.button .check-box .scroll-bar |
你也能够通过节点的ID来定义样式,这个ID由节点的setId()方法进行设置。样式名称前以#开头,例如,一个节点的id是my-button,那么它的样式就是#my-button。
ID样式选择器的例子
#my-button #shaded-hbox |
使用组合的选择器也是可以的。包含元素的一些classes可以有它们自己的子样式定义,例如,许多UI控件有一个label的子class。这些定义的选择器可以通过一个空格和它的子class连接起来。
包含子class的选择器的例子
.check-box .label .check-box .box .radio-button .dot |
伪类也可以用于定义节点的状态,例如当节点获得焦点时。这些定义通过:来和类选择器连接。
包含伪类的选择器的例子:
.radio-button:focused .radio-button:hover .scroll-bar:vertical |
规则和属性
样式定义的规则是给属性赋予一个值的形式。规则属性名和类的属性名相对应。按惯例,属性名一般使用多个单词,用-连接起来。JavaFX样式表的属性名是以-fx-开头的属性名称,属性名和值之间用:隔开,然后以;结尾。
规则的例子
-fx-background-color: #333333; -fx-text-fill: white; -fx-alignment: CENTER; |
.root样式类被应用到Scene实例的root节点中。因为在scene中,所有的节点都是root节点的子节点,.root样式可以应用到任何节点。
.root样式类包含的属性能够被其他样式用来提供UI的一致性。例如,-fx-focused-base属性被其他的UI控件的样式用来定义控件获得焦点时的颜色。下面的定义说明了-fx-focused-base属性是怎样用于CheckBox样式的。
.check-box:focused { -fx-color: -fx-focused-base; } |
美化你的Scene
你可以很便捷的通过.root样式来修饰你的UI控件。实例中前两个样式是设置字体和字的大小,其他的颜色是通过base这项来获取,background设置了scene背景颜色。例37-3,是controlStyle2.css中的.root样式。
例37-3 Root样式
.root{ -fx-font-size: 16pt; -fx-font-family: "Courier New"; -fx-base: rgb(132, 145, 47); -fx-background: rgb(225, 228, 203); } |
美化你的控件
你也可以进一步通过定义各种样式来修饰你的每个控件。你可以覆写默认样式表或者创建新的class样式和id样式。你也可以为你代码中的每个节点定义样式。
覆写默认样式
你可以在你的样式表中覆写默认默认,方法是给样式中的属性进行重新赋值。例37-4,显示了controlStyle2.css中对Button类的样式定义。
例37-4 覆写一个样式
.button{ -fx-text-fill: rgb(49, 89, 23); -fx-border-color: rgb(49, 89, 23); -fx-border-radius: 5; -fx-padding: 3 6 6 6; } |
上面的样式定义了文本颜色,边框颜色,边框尺寸,空白大小。那个按钮的颜色和按钮文本字体的样式则继承自.root 样式。这个按钮的外观见下图。
创建class样式
你可以创建一个class样式,例37-5中显示了controlStyle2.css中定义的一个名叫.button1的样式
例37-5 定义新样式
.button1{ -fx-text-fill: #006464; -fx-background-color: #DFB951; -fx-border-radius: 20; -fx-background-radius: 20; -fx-padding: 5; } |
其外观如下图:
注意:按钮的文本字体继承自controlStyle1.css中定义的.root样式
-为了把这个class样式应用到节点,我们可以使用节点的getStyleClass().add()方法。例37-6中显示了把.button1应用到按钮。
例37-6 应用一个样式
Button buttonAccept = new Button("Accept"); buttonAccept.getStyleClass().add("button1"); |
注意:为节点增加一个样式是有累计效应的。上例中的按钮将同时呈现.button和.button1中的组合样式。
创建一个ID样式
ID样式是以#开头的,如例37-7创建一个#font-button。
例37-7 定义一个ID样式
#font-button { -fx-font: bold italic 20pt "Arial"; -fx-effect: dropshadow( one-pass-box , black , 8 , 0.0 , 2 , 0 ); } |
上例中定义个样式效果如下图:
例37-8 应用ID样式到节点
Button buttonFont = new Button("Font"); buttonFont.setId("font-button"); |
在代码中设置样式
你也可以再代码中设置样式属性,设置在代码中的样式优先于样式表中的样式显示。例37-9显示了怎样在代码中设置一个按钮的背景色和字体颜色。
Button buttonColor = new Button("Color"); buttonColor.setStyle("-fx-background-color: slateblue; -fx-text-fill: white;"); |
效果如下图: