一、JavaFX CSS 概述
JavaFX 支持使用 CSS 来美化界面,与 Web CSS 类似但有自己的特性:
- 样式属性以
-fx-前缀开头 - 支持伪类(
:hover、:focused、:pressed) - 支持类选择器(
.button、.label) - 支持 ID 选择器(
#myButton)
1.1 三种应用 CSS 的方式
| 方式 | 适用场景 | 代码示例 |
|---|---|---|
| 内联样式 | 单个控件临时样式 | button.setStyle("-fx-background-color: red;") |
| 代码中加载 | 程序内动态切换 | scene.getStylesheets().add("style.css") |
| FXML 中引用 | 界面与样式分离 | <VBox stylesheets="@style.css"> |
二、JavaFX CSS 核心属性
2.1 常用样式属性速查
| 属性 | 说明 | 示例 |
|---|---|---|
-fx-background-color | 背景颜色 | #2196F3,linear-gradient(to bottom, #fff, #eee) |
-fx-text-fill | 文字颜色 | white,#333 |
-fx-font-size | 字体大小 | 14px,16px |
-fx-font-family | 字体 | "Consolas","Microsoft YaHei" |
-fx-padding | 内边距 | 10px,5 10 5 10 |
-fx-border-color | 边框颜色 | #ccc |
-fx-border-radius | 边框圆角 | 5px,50% |
-fx-background-radius | 背景圆角 | 8px |
-fx-effect | 阴影效果 | dropshadow(gaussian, rgba(0,0,0,0.3), 10, 0, 0, 2) |
三、按钮样式实战
3.1 基础样式
/* style.css */.button{-fx-background-color:#2196F3;-fx-text-fill:white;-fx-font-size:14px;-fx-padding:8 20;-fx-background-radius:5px;-fx-cursor:hand;}.button:hover{-fx-background-color:#1976D2;}.button:pressed{-fx-background-color:#1565C0;-fx-translate-y:1px;}.button:disabled{-fx-background-color:#ccc;-fx-text-fill:#999;}3.2 多种按钮风格
/* 成功按钮 */.button-success{-fx-background-color:#4CAF50;}.button-success:hover{-fx-background-color:#43A047;}/* 危险按钮 */.button-danger{-fx-background-color:#f44336;}.button-danger:hover{-fx-background-color:#e53935;}/* 警告按钮 */.button-warning{-fx-background-color:#FF9800;}.button-warning:hover{-fx-background-color:#F57C00;}/* 圆角大按钮 */.button-round{-fx-background-radius:25px;-fx-padding:10 30;}3.3 运行效果
FX Experience 官方展示的 JavaFX CSS 按钮样式集合,包含 Green、Round Red、Bevel Grey、Glass Grey、Shiny Orange、Dark Blue、Record Sales、Rich Blue、Big Yellow 等多种风格,在浅色和深色背景下对比展示。
四、TableView 样式美化
4.1 表格整体样式
/* 表格整体 */.table-view{-fx-background-color:transparent;-fx-border-color:#e0e0e0;-fx-border-radius:5px;}/* 表头 */.table-view .column-header{-fx-background-color:linear-gradient(to bottom,#fafafa,#f0f0f0);-fx-border-color:transparent #e0e0e0 #e0e0e0 transparent;-fx-border-width:0 1 1 0;-fx-padding:10 5;}.table-view .column-header .label{-fx-font-weight:bold;-fx-text-fill:#333;}/* 行样式 */.table-row-cell{-fx-background-color:white;-fx-border-color:transparent transparent #f0f0f0 transparent;}.table-row-cell:odd{-fx-background-color:#fafafa;}.table-row-cell:hover{-fx-background-color:#e3f2fd;}.table-row-cell:selected{-fx-background-color:#bbdefb;-fx-text-fill:#1565C0;}五、完整实战:浅色主题与深色主题
5.1 浅色主题:light-theme.css
/* ===== 根节点 ===== */.root{-fx-background-color:#f5f5f5;-fx-font-family:"Microsoft YaHei","Segoe UI",sans-serif;-fx-font-size:14px;}/* ===== 标签 ===== */.label{-fx-text-fill:#333;}.label-title{-fx-font-size:24px;-fx-font-weight:bold;-fx-text-fill:#1565C0;}.label-subtitle{-fx-font-size:14px;-fx-text-fill:#666;}/* ===== 按钮 ===== */.button{-fx-background-color:#2196F3;-fx-text-fill:white;-fx-padding:8 20;-fx-background-radius:5px;-fx-cursor:hand;-fx-effect:dropshadow(gaussian,rgba(33,150,243,0.3),8,0,0,2);}.button:hover{-fx-background-color:#1976D2;-fx-effect:dropshadow(gaussian,rgba(33,150,243,0.5),12,0,0,4);}.button:pressed{-fx-background-color:#1565C0;-fx-translate-y:1px;}.button-secondary{-fx-background-color:white;-fx-text-fill:#2196F3;-fx-border-color:#2196F3;-fx-border-radius:5px;-fx-border-width:1;-fx-effect:none;}.button-secondary:hover{-fx-background-color:#e3f2fd;}/* ===== 输入框 ===== */.text-field, .password-field, .text-area{-fx-background-color:white;-fx-border-color:#ddd;-fx-border-radius:5px;-fx-padding:8 10;-fx-background-radius:5px;}.text-field:focused, .password-field:focused, .text-area:focused{-fx-border-color:#2196F3;-fx-effect:dropshadow(gaussian,rgba(33,150,243,0.2),8,0,0,0);}/* ===== 菜单栏 ===== */.menu-bar{-fx-background-color:white;-fx-border-color:transparent transparent #e0e0e0 transparent;}.menu:hover, .menu:showing{-fx-background-color:#e3f2fd;}.menu-item:hover{-fx-background-color:#e3f2fd;}/* ===== 面板 ===== */.panel{-fx-background-color:white;-fx-background-radius:8px;-fx-effect:dropshadow(gaussian,rgba(0,0,0,0.08),12,0,0,2);-fx-padding:20;}/* ===== 导航栏 ===== */.nav-panel{-fx-background-color:white;-fx-border-color:transparent #e0e0e0 transparent transparent;}.nav-button{-fx-background-color:transparent;-fx-text-fill:#666;-fx-padding:10 15;-fx-background-radius:5px;-fx-alignment:CENTER_LEFT;-fx-effect:none;}.nav-button:hover{-fx-background-color:#f5f5f5;-fx-text-fill:#333;}.nav-button:selected{-fx-background-color:#e3f2fd;-fx-text-fill:#2196F3;}/* ===== 状态栏 ===== */.status-bar{-fx-background-color:white;-fx-border-color:#e0e0e0 transparent transparent transparent;-fx-padding:5 15;}/* ===== TabPane ===== */.tab-pane .tab-header-area{-fx-padding:5 10 0 10;}.tab{-fx-background-color:transparent;-fx-padding:8 15;}.tab:selected{-fx-background-color:white;-fx-border-color:transparent transparent #2196F3 transparent;-fx-border-width:0 0 2 0;}.tab-label{-fx-text-fill:#666;}.tab:selected .tab-label{-fx-text-fill:#2196F3;-fx-font-weight:bold;}5.2 深色主题:dark-theme.css
/* ===== 根节点 ===== */.root{-fx-background-color:#1e1e1e;-fx-font-family:"Microsoft YaHei","Segoe UI",sans-serif;-fx-font-size:14px;}/* ===== 标签 ===== */.label{-fx-text-fill:#e0e0e0;}.label-title{-fx-font-size:24px;-fx-font-weight:bold;-fx-text-fill:#90caf9;}.label-subtitle{-fx-font-size:14px;-fx-text-fill:#999;}/* ===== 按钮 ===== */.button{-fx-background-color:#2196F3;-fx-text-fill:white;-fx-padding:8 20;-fx-background-radius:5px;-fx-cursor:hand;}.button:hover{-fx-background-color:#42a5f5;}.button:pressed{-fx-background-color:#1976D2;}.button-secondary{-fx-background-color:transparent;-fx-text-fill:#90caf9;-fx-border-color:#90caf9;-fx-border-radius:5px;-fx-border-width:1;}.button-secondary:hover{-fx-background-color:rgba(144,202,249,0.1);}/* ===== 输入框 ===== */.text-field, .password-field, .text-area{-fx-background-color:#2d2d2d;-fx-border-color:#444;-fx-border-radius:5px;-fx-padding:8 10;-fx-text-fill:#e0e0e0;-fx-background-radius:5px;}.text-field:focused, .password-field:focused, .text-area:focused{-fx-border-color:#2196F3;}/* ===== 菜单栏 ===== */.menu-bar{-fx-background-color:#252526;-fx-border-color:transparent transparent #333 transparent;}.menu:hover, .menu:showing{-fx-background-color:#2a2d2e;}.menu-item{-fx-background-color:#252526;}.menu-item:hover{-fx-background-color:#094771;}/* ===== 面板 ===== */.panel{-fx-background-color:#252526;-fx-background-radius:8px;-fx-padding:20;}/* ===== 导航栏 ===== */.nav-panel{-fx-background-color:#252526;-fx-border-color:transparent #333 transparent transparent;}.nav-button{-fx-background-color:transparent;-fx-text-fill:#999;-fx-padding:10 15;-fx-background-radius:5px;-fx-alignment:CENTER_LEFT;}.nav-button:hover{-fx-background-color:#2a2d2e;-fx-text-fill:#e0e0e0;}.nav-button:selected{-fx-background-color:#094771;-fx-text-fill:white;}/* ===== 状态栏 ===== */.status-bar{-fx-background-color:#252526;-fx-border-color:#333 transparent transparent transparent;-fx-padding:5 15;}/* ===== TableView ===== */.table-view{-fx-background-color:transparent;-fx-border-color:#333;}.table-view .column-header{-fx-background-color:#2d2d2d;-fx-border-color:transparent #333 #333 transparent;}.table-view .column-header .label{-fx-text-fill:#e0e0e0;}.table-row-cell{-fx-background-color:#1e1e1e;-fx-border-color:transparent transparent #333 transparent;}.table-row-cell:odd{-fx-background-color:#252526;}.table-row-cell:hover{-fx-background-color:#2a2d2e;}.table-row-cell:selected{-fx-background-color:#094771;}/* ===== TabPane ===== */.tab-pane .tab-header-area{-fx-padding:5 10 0 10;}.tab{-fx-background-color:transparent;-fx-padding:8 15;}.tab:selected{-fx-background-color:#1e1e1e;-fx-border-color:transparent transparent #2196F3 transparent;-fx-border-width:0 0 2 0;}.tab-label{-fx-text-fill:#999;}.tab:selected .tab-label{-fx-text-fill:#90caf9;-fx-font-weight:bold;}六、Java 代码中应用 CSS
6.1 加载外部 CSS 文件
importjavafx.scene.Scene;publicclassThemeAppextendsApplication{privatebooleanisDarkTheme=false;@Overridepublicvoidstart(StageprimaryStage)throwsException{Parentroot=FXMLLoader.load(getClass().getResource("/main.fxml"));Scenescene=newScene(root);// 加载浅色主题scene.getStylesheets().add(getClass().getResource("/light-theme.css").toExternalForm());primaryStage.setScene(scene);primaryStage.show();}/** * 切换主题 */privatevoidtoggleTheme(Scenescene){scene.getStylesheets().clear();if(isDarkTheme){scene.getStylesheets().add(getClass().getResource("/light-theme.css").toExternalForm());}else{scene.getStylesheets().add(getClass().getResource("/dark-theme.css").toExternalForm());}isDarkTheme=!isDarkTheme;}}6.2 FXML 中引用 CSS
<VBoxstylesheets="@light-theme.css"styleClass="root"><!-- 子节点会自动应用样式 --></VBox>6.3 代码中动态设置样式类
Buttonbtn=newButton("主题切换");btn.getStyleClass().add("button-secondary");// 添加样式类// 切换样式类btn.getStyleClass().remove("button-secondary");btn.getStyleClass().add("button-primary");七、运行效果展示
7.1 深色主题效果
Makery 教程中的 AddressApp 深色主题效果,包含菜单栏、人员列表和详情面板,整体采用深色背景配合浅色文字。
7.2 深色主题 TableView
Stack Overflow 上的 JavaFX 深色模式示例,展示了深色背景下的 TableView、按钮和输入框样式。
7.3 现代化主题组件
AtlantaFX 现代化 JavaFX CSS 主题集合,展示了 ToolBar、面包屑导航、按钮等多种控件在深色主题下的效果。
7.4 浅色主题布局
Oracle 官方教程中的 Layout Sample,展示了 CSS 样式化后的布局面板,包含 Sales 数据展示和多种图表类型选择。
7.5 完整组件展示
AtlantaFX 主题展示多种组件:文档编辑、日历选择、任务列表、音乐播放器、数据表格等,采用现代化的卡片式设计风格。
常用 CSS 选择器总结
| 选择器 | 说明 | 示例 |
|---|---|---|
.button | 所有按钮 | 全局按钮样式 |
.button:hover | 鼠标悬停 | 悬停效果 |
.button:pressed | 按下状态 | 点击效果 |
.button:disabled | 禁用状态 | 灰色显示 |
#myButton | ID 选择器 | 特定按钮 |
.button.primary | 类选择器 | 主按钮 |
.text-field:focused | 聚焦状态 | 输入框聚焦 |
.table-row-cell:selected | 选中行 | 表格选中 |
.tab:selected | 选中标签 | Tab 选中 |
.check-box:selected | 选中复选框 | 勾选状态 |