原文地址:DOC-03-37 在UI控件上使用CSS | JavaFX中文资料
JavaFX中使用层叠样式表(CSS),来为你的程序创建自定义外观。
样式表中包含可以控制用户界面元素外观的样式定义。在JavaFX程序中使用CSS与在HTML中使用CSS类似。JavaFX中的CSS建立在W3C CSS 2.1版(参见http://www.w3.org/TR/CSS21)的基础之上,在其中加入了3.0版的部分内容和一些支持特定JavaFX特性的扩展内容。
使用JavaFX CSS来定义皮肤使得你可以仅通过修改样式表
默认样式表
JavaFX程序的默认样式表是modena.css,此文件在JavaFX的运行时jar包(jfxrt.jar)中。该样式表定义了root node和UI控件的样式。要查看该样式文件,请到JDK的安装目录下的\jre\lib\ext 目录下,使用下面的指令从jar包中解压出来:
Java
1 | jar xf jfxrt.jar com/sun/javafx/scene/control/skin/modena/modena.css |
展示了使用默认样式表样例的UI外观。
图默认样式
创建样式表
你可以创建一个或多个样式表来覆盖默认的样式或者是添加你自己的样式。一般来说,创建的样式表都应该以.css为后缀,并且应该与你JavaFX程序的main class放在同一个路径下
样式表被应用到Scene对象上。在该例子中,path表示你的样式表的路径,stylesheet即是你的样式表的名称
Scene scene = new Scene(new Group(), 500, 400);
scene.getStylesheets().add("path/stylesheet.css");
定义样式
一个样式定义由两部分组成:样式的名称,又叫选择器;为该样式设置属性的一系列规则。样式定义的规则由大括号({})括起来
例如:.custom-button的样式定义:
.custom-button {
-fx-font: 16px "Serif";
-fx-padding: 10;
-fx-background-color: #CCFF99;
}
字体的大小可以用点(pt)为单位也可以用像素(px)为单位。JavaFX假定分辨率为96dpi,所以1px=0.75pt
选择器
有多种类型的样式可以被定义。每种类型都有其自己的选择器。
类选择器相当于class名称。按照惯例,当样式的class名称由多个单词组成时,单词之间用连字符(-)连接。类选择器都以点(.)开头
类选择器的样例:
CSS
1 2 3 | .button .check-box .scroll-bar |
你也可以通过node的ID来定义与该node相关联的样式。通过node的setId()方法可以设置node的ID。样式的名称是ID前加个#。例如,一个ID是my-button的node可以通过#my-button来定义样式。
ID选择器的样例:
1 2 | #my-button #shaded-hbox |
也可以使用混合选择器。有的class包含一些元素可以自定义其样式,这种样式叫做子类(descendant class)。例如,许多UI控件都有为label定义一个descendant class。这个定义是通过class的选择器和子类的选择器组合在一起,中间通过空格分开来标识的。
descendant class选择器的样例:
CSS
1 2 3 | .check-box .label .check-box .box .radio-button .dot |
Pseudo-classes使你可以定制node的状态,比如当node获取焦点时。这种定义由该class的选择器和该状态的名称组成,中间用冒号(:)分隔。
在这里寓意为伪属性的意思
Pseudo-classes选择器的样例:
CSS
1 2 3 | .radio-button:focused .radio-button:hover .scroll-bar:vertical |
规则和属性
样式定义中的规则为class的属性设置值。规则属性名称相当于某class的属性名称。有多个单词组成的属性名称的惯例是使用连字符(-)分开每个单词。JavaFX样式表中的属性名称均以-fx-开头。属性名和属性值之间用冒号(:)分隔。规则以分号(;)结尾。
规则样例:
CSS
1 2 3 | -fx-background-color: #333333; -fx-text-fill: white; -fx-alignment: CENTER; |
.root样式类会应用到Scene实例的root node。由于scene中的所有node都在该root node中,.root样式类中的样式能被应用到所有的node上。
.root样式类中包含许多可被其它样式使用的属性,以此来保证UI的一致性。例如,-fx-focused-base属性就是在.root样式类中定义的。此属性用来定义任何其它UI控件获取焦点时的颜色。下面的代码展示了如何在CheckBox的样式中使用该属性:
CSS
1 2 3 | .check-box:focused { -fx-color: -fx-focused-base; } |
为Scene定制皮肤
你可以仅通过修改.root样式类来快速改变UI外观。两个样例的样式表都设置了font size、font family、衍生其他颜色的base color和scene的background color。例37-3展示了controlStyle2.css中的.root样式。
例 controlStyle2.css中的.root样式
1 2 3 4 5 6 | .root{ -fx-font-size: 16pt; -fx-font-family: "Courier New"; -fx-base: rgb(132, 145, 47); -fx-background: rgb(225, 228, 203); } |
仅需要这一个样式就可以创建图中的基础外观。这是因为内置的UI控件都使用了root node的属性集来获得自己的颜色和字体。
为控件定制皮肤
你可以通过为不同控件定义样式来进一步定制你的UI。你可以覆盖默认样式表中的样式定义,或者创建新的类样式或者ID样式。也可以在代码中为某个node定义样式。
覆盖默认样式
在你的样式表中加入某样式并且为它设置不同的属性就可以覆盖该样式在默认样式表中的定义了。例展示了controlStyle2.css中的Button的样式。
例 样式的覆盖
1 2 3 4 5 6 | .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; } |
该样式中定义了font color、border color、border radius和padding。button的颜色和label的字体样式由例中的.root定义。这种样式的Button外观如下图所示
如果在默认的modena.css样式表中没有某个class的样式定义,请在你的样式表中定义该样式并将它分配给每个class,就像例中做的那样。例如,布局面板在modena.css中没有定义样式。请参考Styling Layout Panes with CSS获取更多如何为类创建样式的信息,如HBox和GridPane类等
创建类样式(Class Style)
你可以在你的样式表中为某个class添加一条声明,来创建一个class style。例37-5在controlStyle1.css中声明了一个名为.button1的新样式。
声明新样式
1 2 3 4 5 6 7 | .button1{ -fx-text-fill: #006464; -fx-background-color: #DFB951; -fx-border-radius: 20; -fx-background-radius: 20; -fx-padding: 5; } |
任何添加了这个样式的button都会显示如下图。注意按钮上的文字的字体是由 controlStyle1.css中的.root声明继承下来的。
要把这个样式分配到node,使用getStyleClass().add()方法。.button1样式应用给Accept button。
分配Class Style
Java
1 2 | Button buttonAccept = new Button("Accept"); buttonAccept.getStyleClass().add("button1"); |
需要注意的是,为node添加样式是累加式的。为buttonAccept这个node添加了.button1样式以后,该node就会同时使用.button和.button1两个样式规则
创建ID样式
你可以通过创建一个样式并且将它分配给某个独立的node来为该node声明一个样式。该样式的名字是ID前加个井号(#)
创建了一个名为#font-button的样式声明
声明ID样式
CSS
1 2 3 4 | #font-button { -fx-font: bold italic 20pt "Arial"; -fx-effect: dropshadow( one-pass-box , black , 8 , 0.0 , 2 , 0 ); } |
ID为font-button的button外观如下图所示:
分配ID样式
Java
1 2 | Button buttonFont = new Button("Font"); buttonFont.setId("font-button"); |
在代码中设置样式
你也可以在代码中为node设置样式属性。在代码中设置的样式优先级要高于通过css文件设置的样式
改变button的background color和font color。
例声明内联样式(Style Inline)
Java
1 2 | Button buttonColor = new Button("Color"); buttonColor.setStyle("-fx-background-color: slateblue; -fx-text-fill: white;"); |
下图展示了上面代码定义的按钮外观