JavaFX入门(五):使用CSS样式美化你的UI控件

CSS(层叠样式表,Cascading Style Sheets)原来是被用来在网页开发中表现HTML元素样式的一种文本标记语言。HTML用来展现内容,CSS被用来设计内容的样式,这样做的好处就是内容和样式相分离。CSS先后被用到Adobe的RIA开发技术Flex,C++的GUI框架Qt以及JavaFX技术上。如果对CSS不是很熟悉,没关系,十分钟入门CSS的一个教程:W3CSchool CSS教程

JavaFX的CSS样式基于W3C CSS的2.1版本,是CSS 2.1的一个子集,不包含CSS 2.1的所有特性。同时JavaFX对该版本的CSS有所扩展。参考文档:JavaFX CSS Reference Guide。 JavaFX CSS有三种选择器: 1. type selector 每个JavaFX控件类都对应这一个CSS Type,我们可以使用类型选择器,控制该类型控件的外观。其对应的命名为:将JavaFX的类名成首字母小写,如果是由多个单词拼接的类名,将每个单词原来大写的首字母小写然后用连字符将多个单词连接。比如:

JavaFX Class

CSS type class

Button

button

Label

label

CheckBox

check-box

TextField

text-field

类型选择器的用法如下:

.button {
    -fx-background-color: blue;
}

这样我们就设置了所有Button的背景色为蓝色。其实类型选择器我们可以看做一种特殊的类选择器。 CSS中属性的命名规则是:以-fx开头,然后连接该类的属性,属性名称的单词首字母小写,然后用连字符连接拼接的属性单词。比如上面的-fx-background-color对应着Button的backgroundColor属性。具体的CSS属性我们可以参考JavaFX CSS Reference Guide文档。 2. class selector 类选择器和W3C的CSS中类选择器是一样的。比如下面的用法:

.font-large {
    -fx-font-size: 16pt;
}

我们定义了一个font–large的类选择器。对于Node的任意子类都有一个getStyleClass()的方法,我们可以通过getStyleClass().add(“font-large”);将给类样式添加到指定的控件上。一个类选择器样式可以应用到多个控件上。 3. id selector 一个典型的ID选择器如下:

#lbl-title {
    -fx-font-color: red;
    -fx-font-size: 20px;
    -fx-font-weight: bolder;
}

ID选择器由#开始进行定义。一般情况下一个ID选择器对应这唯一的一个控件。比如我们有一个ID为libTitle的Label,那么通过该CSS这个Label的字体会进行相应的改变。

Label lblTitle = new Label("欢迎来到中国");
lalTitle.setId("lbl-title");

最后说的是伪类选择器: 伪类的语法为:selector : pseudo-class {property: value} 比如我们设置当鼠标移动到Button上去时背景色变为绿色:

.button:hover {
    -fx-background-color: green;
}

JavaFX中Node类定义的伪类有:

CSS Pseudo-class

Comments

disabled

applies when the disabled variable is true

focused

applies when the focused variable is true

hover

applies when the hover variable is true

pressed

applies when the pressed variable is true

show-mnemonic

apples when the mnemonic affordance (typically an underscore) should be shown.

对于JavaFX中伪类元素我们可以查阅Oracle 的在线文档进行浏览和查询。


下面我们使用CSS美化一下我们在《JavaFX入门(三):使用Eclipse开发JavaFX程序 》一节中使用SceneBuilder拖拽出来的界面。

Eclipse中新建Java工程如下:

MainApplication.java文件是我们的主类文件,MainWindow.fxml是我们的FXML界面布局文件,MainStyle.css是我们的CSS样式文档。 我们的主界面使用GridPane,一个4×3的格网。第一行第一列是ImageVeiw用于显示Logo图标,第二列是Label用于显示标题;第二行第一列是一个Label(用户名),第二行第二列和第三列是一个TextFiled用于输入用户名;第三行第一列是一个Label(密码),第三行第二列和第三列是一个PasswordFiled用于输入密码。第四行第二列和第三列是一个AnchorPane,AnchorPane中是两个Button,一个锚定到左边,一个锚定到右边。在SceneBuilder中的设计图如下: MainWindow.fxml代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>

<GridPane prefHeight="320.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
    <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" maxWidth="129.0" minWidth="10.0" prefWidth="100.0" />
        <ColumnConstraints hgrow="SOMETIMES" maxWidth="225.0" minWidth="10.0" prefWidth="220.0" />
      <ColumnConstraints hgrow="SOMETIMES" maxWidth="99.0" minWidth="10.0" prefWidth="80.0" />
    </columnConstraints>
    <rowConstraints>
      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
    </rowConstraints>
   <children>
      <Label fx:id="lblTitle" text="欢迎使用物联网系统" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
      <Label text="用户名:" GridPane.halignment="RIGHT" GridPane.rowIndex="1" GridPane.valignment="CENTER" />
      <TextField GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="1">
         <GridPane.margin>
            <Insets left="20.0" right="50.0" />
         </GridPane.margin>
      </TextField>
      <Label text="密 码:" GridPane.halignment="RIGHT" GridPane.rowIndex="2" GridPane.valignment="CENTER" />
      <PasswordField GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="2">
         <GridPane.margin>
            <Insets left="20.0" right="50.0" />
         </GridPane.margin>
      </PasswordField>
      <AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="3">
         <children>
            <Button layoutX="14.0" layoutY="17.0" mnemonicParsing="false" text="取消" AnchorPane.leftAnchor="20.0" />
            <Button layoutX="197.0" layoutY="17.0" mnemonicParsing="false" text="登录" AnchorPane.rightAnchor="50.0" />
         </children>
      </AnchorPane>
      <ImageView fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@images/earth.png" />
         </image>
         <GridPane.margin>
            <Insets left="20.0" />
         </GridPane.margin>
      </ImageView>
   </children>
</GridPane>

运行图如下:

我们的主函数MainApplication.java代码如下:

package cn.tzy.fx.application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class MainApplication extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        try {
            GridPane root = (GridPane) FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
            Scene scene = new Scene(root, 400, 320);
            primaryStage.setScene(scene);
            primaryStage.setTitle("Hello World");
            primaryStage.setResizable(false);
            primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("images/earth.png")));
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        launch(args);
    }


}

下面我们利用CSS调整界面样式:

/*root类选择器给所有的元素设置样式*/
.root {
    -fx-font-family: "微软雅黑";
    -fx-font-size: 16px;
    -fx-background-image: url(images/background.png);
    -fx-background-size: stretch stretch;
    -fx-background-position: center center;
}

/*button类型选择器设置所有Button的背景色*/
.button {
    -fx-background-color: darkturquoise;
}

/*hover伪类选择器设置鼠标移过Button时的背景色*/
.button:hover {
    -fx-background-color: lightskyblue;
}

/*id选择器设置Label标题的样式*/
#lblTitle {
    -fx-font-size: 20px;
    -fx-font-weight: bolder;
    -fx-text-fill: darkslategray;
}

如何将我们的CSS样式文件添加上去呢? 1. 在主程序的start()方法中添加一句代码:scene.getStylesheets().add( getClass().getResource("MainStyle.css") .toExternalForm()); 2. 在我们的FXML文件中给根布局控件GridPane添加属性stylesheets="@MainStyle.css"即可,注意是@后面跟我们的CSS文件路径全名称。 看看最终运行效果吧!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券