javafx-ui-designer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJavaFX UI Designer — Renamer App
JavaFX UI 设计师——Renamer App
Purpose: Guide the design of visually polished, usable, and consistent JavaFX interfaces for the Renamer App. Covers layout composition, color palettes, typography, spacing systems, CSS styling, control theming, accessibility, and responsive design.Supporting files in this directory:
— CSS property reference + full control styling patterns (sections 7–8)css-control-patterns.md — theming architecture, responsive design, CSS transitions (sections 9, 11–12)theming-and-motion.md
目的:指导Renamer App打造视觉精致、易用且一致的JavaFX界面,涵盖布局组合、调色板、排版、间距系统、CSS样式、控件主题、可访问性及响应式设计。本目录下的支持文件:
— CSS属性参考+完整控件样式模式(第7-8节)css-control-patterns.md — 主题架构、响应式设计、CSS过渡效果(第9、11-12节)theming-and-motion.md
1. Project Context
1. 项目背景
yaml
project_name: "Renamer App"
javafx_version: 25
java_version: 25
build_tool: maven
css_location: app/ui/src/main/resources/styles/ # create this dir; no CSS files exist yet
fxml_location: app/ui/src/main/resources/fxml/
target_platform: desktop
design_style: modern-flat
color_scheme: light # dark/auto as future option
primary_color: "#2196F3" # placeholder — replace when theme is chosen
secondary_color: "#FF9800"
base_font_family: "System" # platform default; replace with Inter/Segoe later
base_font_size: 14px
spacing_unit: 8px
min_window_width: 900
min_window_height: 600
scene_builder_used: false # Guice controllers; no fx:controller attribute
existing_theme: none # Modena default — no AtlantaFX/JMetroyaml
project_name: "Renamer App"
javafx_version: 25
java_version: 25
build_tool: maven
css_location: app/ui/src/main/resources/styles/ # create this dir; no CSS files exist yet
fxml_location: app/ui/src/main/resources/fxml/
target_platform: desktop
design_style: modern-flat
color_scheme: light # dark/auto as future option
primary_color: "#2196F3" # placeholder — replace when theme is chosen
secondary_color: "#FF9800"
base_font_family: "System" # platform default; replace with Inter/Segoe later
base_font_size: 14px
spacing_unit: 8px
min_window_width: 900
min_window_height: 600
scene_builder_used: false # Guice controllers; no fx:controller attribute
existing_theme: none # Modena default — no AtlantaFX/JMetroCritical Project Notes
关键项目说明
- No CSS files exist yet. All current styling is either inline () or stored in
node.setStyle(...). Creating the first CSS file requires addingua.renamer.app.ui.enums.TableStylesinscene.getStylesheets().add(...)before the stage is shown.RenamerApplication.start() - enum holds hardcoded inline style strings for error/ready row states. When introducing a CSS file, migrate these to style classes (
TableStyles,.error) applied programmatically in.ready's row factory.ApplicationMainViewController - Stylesheet load point: — the
RenamerApplicationsubclass atApplication. Launcher entry point:ua.renamer.app.RenamerApplication.ua.renamer.app.Launcher - CSS file location: place all stylesheets under . Load order matters — see
app/ui/src/main/resources/styles/for the correct sequence.theming-and-motion.md
- 目前无CSS文件。当前所有样式要么是内联样式(),要么存储在
node.setStyle(...)中。创建首个CSS文件需要在ua.renamer.app.ui.enums.TableStyles方法中,在显示舞台之前添加RenamerApplication.start()。scene.getStylesheets().add(...) - 枚举保存了用于错误/就绪行状态的硬编码内联样式字符串。引入CSS文件时,需将这些样式迁移到样式类(
TableStyles,.error),并在.ready的行工厂中以编程方式应用。ApplicationMainViewController - 样式表加载点:——位于
RenamerApplication的ua.renamer.app.RenamerApplication子类。启动入口点:Application。ua.renamer.app.Launcher - CSS文件位置:将所有样式表放在下。加载顺序很重要——请查看
app/ui/src/main/resources/styles/获取正确顺序。theming-and-motion.md
2. Design Philosophy
2. 设计理念
Apply these principles in order of priority:
Clarity first — Every element should communicate its purpose immediately. Avoid decorative
complexity that obscures function. Use whitespace generously to let content breathe.
Consistency — Establish a design system (colors, spacing, typography scale) and apply it
uniformly. A consistent interface builds trust and reduces cognitive load. Define tokens once
in CSS looked-up colors on and reference them everywhere.
.rootHierarchy — Guide the user's eye through size, weight, color contrast, and spatial grouping.
Primary actions should be visually prominent; secondary actions should be visually subdued.
Feedback — Every interactive element should respond to user interaction. JavaFX CSS supports
pseudo-classes (, , , , ) and CSS transitions
(JavaFX 23+, available in this project on JavaFX 25) for smooth state changes.
:hover:focused:pressed:disabled:selectedPlatform respect — Desktop applications have different expectations than web or mobile.
Users expect keyboard navigation, focus indicators, tooltips, context menus, and window resizing.
Design for these affordances.
按优先级应用以下原则:
清晰度优先——每个元素应立即传达其用途。避免会掩盖功能的装饰性复杂设计。充分利用留白让内容更易阅读。
一致性——建立设计系统(颜色、间距、排版比例)并统一应用。一致的界面能建立信任并降低认知负荷。在的CSS查找颜色中定义一次令牌,然后在各处引用。
.root层级结构——通过尺寸、字重、颜色对比度和空间分组引导用户视线。主要操作应在视觉上突出;次要操作应在视觉上弱化。
反馈机制——每个交互元素都应响应用户操作。JavaFX CSS支持伪类(, , , , )和CSS过渡效果(JavaFX 23+,本项目基于JavaFX 25支持该特性),实现平滑的状态切换。
:hover:focused:pressed:disabled:selected适配平台特性——桌面应用与网页或移动应用的预期不同。用户期望支持键盘导航、焦点指示器、工具提示、上下文菜单和窗口调整大小。设计时需考虑这些特性。
3. Layout System & Composition
3. 布局系统与组合
Layout Pane Selection Guide
布局面板选择指南
VBox — Stack children vertically with uniform spacing. Use for forms, lists of controls,
sidebar menus, or any top-to-bottom flow. Set for gaps and
for horizontal positioning.
-fx-spacing-fx-alignmentHBox — Stack children horizontally. Use for toolbars, button rows, inline form fields.
BorderPane — Classic 5-region layout (top, bottom, left, right, center). Use as the root
layout for application windows. The center region grows to fill available space. Toolbars go in
top, status bars in bottom, navigation in left.
GridPane — Two-dimensional grid for structured forms and data entry layouts. Use
and for sizing control. Use / for gutters.
columnConstraintsrowConstraintshgapvgapStackPane — Layer children on top of each other. Use for overlays, loading indicators,
or combining a background with foreground elements.
FlowPane — Wrapping flow layout. Children wrap to the next row when space runs out.
Use for tag clouds, icon grids, or chip/badge collections.
TilePane — Like FlowPane but all tiles are uniform size. Good for dashboards, image
galleries, or card grids.
AnchorPane — Pin children to edges with pixel offsets. Use sparingly — creates rigid
layouts that don't adapt to resizing.
VBox——垂直堆叠子元素,间距均匀。适用于表单、控件列表、侧边栏菜单或任何从上到下的流布局。设置控制间隙,控制水平位置。
-fx-spacing-fx-alignmentHBox——水平堆叠子元素。适用于工具栏、按钮行、内联表单字段。
BorderPane——经典的5区域布局(顶部、底部、左侧、右侧、中心)。用作应用窗口的根布局。中心区域会自动填充可用空间。工具栏放在顶部,状态栏放在底部,导航栏放在左侧。
GridPane——二维网格,适用于结构化表单和数据输入布局。使用和控制尺寸。使用/控制 gutter( gutter指网格间的间隙)。
columnConstraintsrowConstraintshgapvgapStackPane——将子元素层叠放置。适用于覆盖层、加载指示器,或结合背景与前景元素。
FlowPane——自动换行的流式布局。当空间不足时,子元素会换行到下一行。适用于标签云、图标网格或芯片/徽章集合。
TilePane——类似FlowPane,但所有 tiles(指布局块)尺寸统一。适用于仪表板、图片画廊或卡片网格。
AnchorPane——通过像素偏移将子元素固定到边缘。谨慎使用——会创建无法自适应调整大小的刚性布局。
Layout Composition Rules
布局组合规则
Nest layouts purposefully:
BorderPane (root)
├── top: VBox
│ ├── MenuBar
│ └── HBox (toolbar)
├── left: VBox (sidebar/navigation)
├── center: StackPane
│ └── ScrollPane
│ └── VBox (content)
├── bottom: HBox (status bar)Set grow priorities to control which children expand on resize:
java
HBox.setHgrow(contentArea, Priority.ALWAYS);
VBox.setVgrow(scrollPane, Priority.ALWAYS);In FXML:
xml
<HBox>
<Label text="Fixed" />
<Region HBox.hgrow="ALWAYS" /> <!-- spacer -->
<Button text="Action" />
</HBox>In this project:usesApplicationMainView.fxmlas root. Mode views useBorderPane. Prefer constraint-based growth overVBox/HBox/GridPane. TheAnchorPanedrivesFxStateMirrordata — do not replace theTableViewbinding on the table.ObservableList
有目的地嵌套布局:
BorderPane (root)
├── top: VBox
│ ├── MenuBar
│ └── HBox (toolbar)
├── left: VBox (sidebar/navigation)
├── center: StackPane
│ └── ScrollPane
│ └── VBox (content)
├── bottom: HBox (status bar)设置增长优先级以控制窗口调整大小时哪些子元素会扩展:
java
HBox.setHgrow(contentArea, Priority.ALWAYS);
VBox.setVgrow(scrollPane, Priority.ALWAYS);在FXML中:
xml
<HBox>
<Label text="Fixed" />
<Region HBox.hgrow="ALWAYS" /> <!-- spacer -->
<Button text="Action" />
</HBox>本项目说明:使用ApplicationMainView.fxml作为根布局。模式视图使用BorderPane。优先使用基于约束的增长方式,而非VBox/HBox/GridPane。AnchorPane驱动FxStateMirror数据——请勿替换表格上的TableView绑定。ObservableList
4. Color System
4. 颜色系统
Defining Colors with Looked-Up Colors
使用查找颜色定义颜色
JavaFX CSS supports "looked-up colors" — define all tokens on , reference them everywhere.
This is the foundation of themeable design.
.rootcss
.root {
/* ── Primary palette ── */
-fx-primary: #2196F3;
-fx-primary-hover: derive(-fx-primary, -10%);
-fx-primary-pressed: derive(-fx-primary, -20%);
-fx-primary-subtle: derive(-fx-primary, 85%);
/* ── Neutral palette ── */
-fx-bg-base: #FFFFFF;
-fx-bg-surface: #F8F9FA;
-fx-bg-elevated: #FFFFFF;
-fx-border-default: #DEE2E6;
-fx-border-subtle: #E9ECEF;
/* ── Text palette ── */
-fx-text-primary: #212529;
-fx-text-secondary: #6C757D;
-fx-text-tertiary: #ADB5BD;
-fx-text-on-primary: #FFFFFF;
/* ── Semantic palette ── */
-fx-success: #28A745;
-fx-warning: #FFC107;
-fx-danger: #DC3545;
-fx-info: #17A2B8;
/* ── Assign to built-in looked-up colors ── */
-fx-base: -fx-bg-base;
-fx-background: -fx-bg-surface;
-fx-accent: -fx-primary;
-fx-focus-color: derive(-fx-primary, 40%);
-fx-faint-focus-color: transparent;
}JavaFX CSS支持“查找颜色”——在上定义所有令牌,然后在各处引用。这是可主题化设计的基础。
.rootcss
.root {
/* ── Primary palette ── */
-fx-primary: #2196F3;
-fx-primary-hover: derive(-fx-primary, -10%);
-fx-primary-pressed: derive(-fx-primary, -20%);
-fx-primary-subtle: derive(-fx-primary, 85%);
/* ── Neutral palette ── */
-fx-bg-base: #FFFFFF;
-fx-bg-surface: #F8F9FA;
-fx-bg-elevated: #FFFFFF;
-fx-border-default: #DEE2E6;
-fx-border-subtle: #E9ECEF;
/* ── Text palette ── */
-fx-text-primary: #212529;
-fx-text-secondary: #6C757D;
-fx-text-tertiary: #ADB5BD;
-fx-text-on-primary: #FFFFFF;
/* ── Semantic palette ── */
-fx-success: #28A745;
-fx-warning: #FFC107;
-fx-danger: #DC3545;
-fx-info: #17A2B8;
/* ── Assign to built-in looked-up colors ── */
-fx-base: -fx-bg-base;
-fx-background: -fx-bg-surface;
-fx-accent: -fx-primary;
-fx-focus-color: derive(-fx-primary, 40%);
-fx-faint-focus-color: transparent;
}The derive()
and ladder()
Functions
derive()ladder()derive()
和ladder()
函数
derive()ladder()derive(color, percentage)ladder(color, stop1, stop2, ...)css
.label {
-fx-text-fill: ladder(-fx-background,
-fx-text-on-primary 49%,
-fx-text-primary 50%
);
}derive(color, percentage)ladder(color, stop1, stop2, ...)css
.label {
-fx-text-fill: ladder(-fx-background,
-fx-text-on-primary 49%,
-fx-text-primary 50%
);
}Color Contrast Guidelines
颜色对比度指南
- Body text: at least 4.5:1 contrast ratio (WCAG AA)
- Large text (18px+ or 14px+ bold): at least 3:1 contrast ratio
- Use to generate accessible hover/pressed states from base colors
derive() - Test palette in both light and dark contexts if supporting both themes
- 正文文本:对比度至少为4.5:1(WCAG AA标准)
- 大文本(18px+或14px+粗体):对比度至少为3:1
- 使用从基础颜色生成符合可访问性要求的悬停/按下状态
derive() - 如果支持双主题,需在浅色和深色环境下测试调色板
Anti-Patterns
反模式
- Never hardcode hex colors directly on controls — always reference looked-up color tokens
- Avoid pure black () on pure white (
#000000) — use slightly tinted neutrals#FFFFFF - Avoid more than 3–4 distinct hues — rely on shades/tints of a few base colors
- 切勿在控件上直接硬编码十六进制颜色——始终引用查找颜色令牌
- 避免在纯白()背景上使用纯黑(
#FFFFFF)——使用略带色调的中性色#000000 - 避免使用超过3-4种不同色调——依赖少数基础颜色的深浅/色调变化
5. Typography
5. 排版
Font Loading
字体加载
java
// Load before scene creation
Font.loadFont(getClass().getResourceAsStream("/fonts/Inter-Regular.ttf"), 14);
Font.loadFont(getClass().getResourceAsStream("/fonts/Inter-Bold.ttf"), 14);css
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-Regular.ttf');
}java
// Load before scene creation
Font.loadFont(getClass().getResourceAsStream("/fonts/Inter-Regular.ttf"), 14);
Font.loadFont(getClass().getResourceAsStream("/fonts/Inter-Bold.ttf"), 14);css
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-Regular.ttf');
}Type Scale
字体比例
Define on and apply via style classes. 1.25 ratio (Major Third) for harmonious sizing:
.rootcss
.root {
-fx-font-family: "System";
-fx-font-size: 14px;
/* ── Type scale (1.25 ratio) ── */
-fx-font-size-xs: 10px;
-fx-font-size-sm: 12px;
-fx-font-size-base: 14px;
-fx-font-size-md: 16px;
-fx-font-size-lg: 18px;
-fx-font-size-xl: 22px;
-fx-font-size-2xl: 28px;
-fx-font-size-3xl: 34px;
}
.h1 {
-fx-font-size: -fx-font-size-3xl;
-fx-font-weight: bold;
-fx-text-fill: -fx-text-primary;
}
.h2 {
-fx-font-size: -fx-font-size-2xl;
-fx-font-weight: bold;
-fx-text-fill: -fx-text-primary;
}
.h3 {
-fx-font-size: -fx-font-size-xl;
-fx-font-weight: 600;
-fx-text-fill: -fx-text-primary;
}
.subtitle {
-fx-font-size: -fx-font-size-md;
-fx-text-fill: -fx-text-secondary;
}
.caption {
-fx-font-size: -fx-font-size-xs;
-fx-text-fill: -fx-text-tertiary;
}
.monospace {
-fx-font-family: "JetBrains Mono", "Consolas", monospace;
}在上定义并通过样式类应用。使用1.25比例(大三度)实现和谐的尺寸层级:
.rootcss
.root {
-fx-font-family: "System";
-fx-font-size: 14px;
/* ── Type scale (1.25 ratio) ── */
-fx-font-size-xs: 10px;
-fx-font-size-sm: 12px;
-fx-font-size-base: 14px;
-fx-font-size-md: 16px;
-fx-font-size-lg: 18px;
-fx-font-size-xl: 22px;
-fx-font-size-2xl: 28px;
-fx-font-size-3xl: 34px;
}
.h1 {
-fx-font-size: -fx-font-size-3xl;
-fx-font-weight: bold;
-fx-text-fill: -fx-text-primary;
}
.h2 {
-fx-font-size: -fx-font-size-2xl;
-fx-font-weight: bold;
-fx-text-fill: -fx-text-primary;
}
.h3 {
-fx-font-size: -fx-font-size-xl;
-fx-font-weight: 600;
-fx-text-fill: -fx-text-primary;
}
.subtitle {
-fx-font-size: -fx-font-size-md;
-fx-text-fill: -fx-text-secondary;
}
.caption {
-fx-font-size: -fx-font-size-xs;
-fx-text-fill: -fx-text-tertiary;
}
.monospace {
-fx-font-family: "JetBrains Mono", "Consolas", monospace;
}Typography Best Practices
排版最佳实践
- Set on
-fx-font-sizeto establish the base — all em-relative sizes scale from it.root - Use no more than 2 font families (one for UI, one for code/data)
- Limit font weights to regular (400) and bold (700); semi-bold (600) for subheadings
- JavaFX text properties: ,
-fx-font-family,-fx-font-size,-fx-font-weight,-fx-font-style,-fx-text-fill,-fx-text-alignment-fx-line-spacing
- 在上设置
.root以建立基础——所有相对em尺寸都以此为基准缩放-fx-font-size - 使用不超过2种字体(一种用于UI,一种用于代码/数据)
- 限制字重为常规(400)和粗体(700);半粗体(600)用于副标题
- JavaFX文本属性:,
-fx-font-family,-fx-font-size,-fx-font-weight,-fx-font-style,-fx-text-fill,-fx-text-alignment-fx-line-spacing
6. Spacing & Sizing System
6. 间距与尺寸系统
Spacing Scale
间距比例
Use 8px as base unit. Define as looked-up values on :
.rootcss
.root {
/* ── Spacing scale (8px base) ── */
-fx-spacing-xs: 4px;
-fx-spacing-sm: 8px;
-fx-spacing-md: 12px;
-fx-spacing-lg: 16px;
-fx-spacing-xl: 24px;
-fx-spacing-2xl: 32px;
-fx-spacing-3xl: 48px;
}Apply via style classes or directly:
css
.card {
-fx-padding: -fx-spacing-lg;
-fx-spacing: -fx-spacing-md;
}以8px为基础单位。在上定义为查找值:
.rootcss
.root {
/* ── Spacing scale (8px base) ── */
-fx-spacing-xs: 4px;
-fx-spacing-sm: 8px;
-fx-spacing-md: 12px;
-fx-spacing-lg: 16px;
-fx-spacing-xl: 24px;
-fx-spacing-2xl: 32px;
-fx-spacing-3xl: 48px;
}通过样式类或直接应用:
css
.card {
-fx-padding: -fx-spacing-lg;
-fx-spacing: -fx-spacing-md;
}Sizing Controls
控件尺寸
Three constraints: , , .
minWidth/HeightprefWidth/HeightmaxWidth/Height- Set for ideal size
prefWidth/Height - Set to
maxWidthin CSS (orInfinityin Java) to allow stretchingDouble.MAX_VALUE - Use (-1) to let JavaFX compute automatically
Region.USE_COMPUTED_SIZE - Avoid hardcoding pixel sizes unless the element truly must be fixed
css
.stretch-button {
-fx-max-width: Infinity;
}
.sidebar {
-fx-pref-width: 240px;
-fx-min-width: 200px;
-fx-max-width: 280px;
}三个约束:, , 。
minWidth/HeightprefWidth/HeightmaxWidth/Height- 设置为理想尺寸
prefWidth/Height - 在CSS中设置为
maxWidth(或Java中的Infinity)以允许拉伸Double.MAX_VALUE - 使用(-1)让JavaFX自动计算
Region.USE_COMPUTED_SIZE - 除非元素确实需要固定尺寸,否则避免硬编码像素尺寸
css
.stretch-button {
-fx-max-width: Infinity;
}
.sidebar {
-fx-pref-width: 240px;
-fx-min-width: 200px;
-fx-max-width: 280px;
}The Box Model in JavaFX
JavaFX中的盒模型
Every is painted bottom to top:
Region┌─────────────────────────────────────┐
│ background-color │
│ ┌───────────────────────────────┐ │ ← background-insets
│ │ border-color │ │
│ │ ┌─────────────────────────┐ │ │ ← border-width + border-insets
│ │ │ padding │ │ │
│ │ │ ┌───────────────────┐ │ │ │ ← padding
│ │ │ │ CONTENT AREA │ │ │ │
│ │ │ └───────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘Multiple backgrounds can be layered with comma-separated values for depth effects:
css
.card-elevated {
-fx-background-color:
derive(-fx-border-default, -5%), /* outer shadow layer */
-fx-border-default, /* border layer */
-fx-bg-elevated; /* content background */
-fx-background-insets: -1, 0, 1;
-fx-background-radius: 9, 8, 7;
}每个从下到上绘制:
Region┌─────────────────────────────────────┐
│ background-color │
│ ┌───────────────────────────────┐ │ ← background-insets
│ │ border-color │ │
│ │ ┌─────────────────────────┐ │ │ ← border-width + border-insets
│ │ │ padding │ │ │
│ │ │ ┌───────────────────┐ │ │ │ ← padding
│ │ │ │ CONTENT AREA │ │ │ │
│ │ │ └───────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘可以使用逗号分隔的值设置多层背景以实现深度效果:
css
.card-elevated {
-fx-background-color:
derive(-fx-border-default, -5%), /* outer shadow layer */
-fx-border-default, /* border layer */
-fx-bg-elevated; /* content background */
-fx-background-insets: -1, 0, 1;
-fx-background-radius: 9, 8, 7;
}10. Accessibility & Usability
10. 可访问性与可用性
Focus Indicators
焦点指示器
Never remove focus indicators entirely. Style them to match your design:
css
.button:focused {
-fx-border-color: -fx-primary;
-fx-border-width: 2px;
}Override global focus appearance on :
.rootcss
.root {
-fx-focus-color: derive(-fx-primary, 20%);
-fx-faint-focus-color: transparent; /* removes outer glow */
}切勿完全移除焦点指示器。根据设计风格设置其样式:
css
.button:focused {
-fx-border-color: -fx-primary;
-fx-border-width: 2px;
}在上覆盖全局焦点外观:
.rootcss
.root {
-fx-focus-color: derive(-fx-primary, 20%);
-fx-faint-focus-color: transparent; /* removes outer glow */
}Keyboard Navigation
键盘导航
- All interactive controls must be reachable via Tab / Shift+Tab
- Use on custom interactive nodes
focusTraversable="true" - Group related controls so Tab order is logical (top-to-bottom, left-to-right)
- Provide mnemonics: creates Alt+S shortcut
_Save - Use properties for keyboard shortcuts
accelerator
- 所有交互控件必须可通过Tab/Shift+Tab访问
- 在自定义交互节点上设置
focusTraversable="true" - 对相关控件进行分组,使Tab顺序符合逻辑(从上到下,从左到右)
- 提供助记符:创建Alt+S快捷键
_Save - 使用属性设置键盘快捷键
accelerator
Tooltips
工具提示
Add tooltips to icon-only buttons and controls whose purpose isn't immediately obvious:
css
.tooltip {
-fx-background-color: -fx-text-primary;
-fx-text-fill: -fx-bg-base;
-fx-font-size: -fx-font-size-sm;
-fx-background-radius: 4px;
-fx-padding: 4px 8px;
}Existing pattern: controllers createin Java viaTooltip. The CSScontrol.setTooltip(new Tooltip(...))rule styles them globally without changing any Java code..tooltip { }
为仅含图标的按钮和用途不明确的控件添加工具提示:
css
.tooltip {
-fx-background-color: -fx-text-primary;
-fx-text-fill: -fx-bg-base;
-fx-font-size: -fx-font-size-sm;
-fx-background-radius: 4px;
-fx-padding: 4px 8px;
}现有模式:控制器通过Java代码创建,即Tooltip。CSS中的control.setTooltip(new Tooltip(...))规则可全局设置其样式,无需修改任何Java代码。.tooltip { }
Minimum Target Sizes
最小目标尺寸
Interactive elements should have a minimum clickable area of 32×32 pixels:
css
.icon-button {
-fx-min-width: 36px;
-fx-min-height: 36px;
-fx-padding: 8px;
}交互元素的最小可点击区域应为32×32像素:
css
.icon-button {
-fx-min-width: 36px;
-fx-min-height: 36px;
-fx-padding: 8px;
}Color Accessibility
颜色可访问性
- Don't convey information through color alone — combine with icons, text, or patterns
- Test color palettes for colorblind accessibility (protanopia, deuteranopia, tritanopia)
- Error states must have both color change AND an icon/text indicator
- 不要仅通过颜色传达信息——结合图标、文本或图案
- 测试调色板的色盲友好性(红色盲、绿色盲、蓝色盲)
- 错误状态必须同时改变颜色并添加图标/文本指示器
13. Design Audit Checklist
13. 设计审核清单
Color & Contrast
颜色与对比度
- All colors come from looked-up color tokens defined on
.root - No hardcoded hex colors on individual controls
- Text has sufficient contrast against its background (4.5:1 minimum)
- Color is not the sole indicator of state (error, success, etc.)
- Hover and pressed states are visually distinct from default state
- 所有颜色均来自上定义的查找颜色令牌
.root - 单个控件上无硬编码十六进制颜色
- 文本与背景的对比度足够(最小4.5:1)
- 颜色不是状态(错误、成功等)的唯一指示器
- 悬停和按下状态与默认状态在视觉上有明显区别
Typography
排版
- A single base font size is set on
.root - A consistent type scale is used (no arbitrary font sizes)
- No more than 2 font families in use
- Text truncation is handled gracefully ()
-fx-text-overrun: ellipsis - Long text wraps or scrolls where appropriate
- 在上设置了单一基础字体大小
.root - 使用了一致的字体比例(无任意字体大小)
- 使用的字体不超过2种
- 文本截断处理得当()
-fx-text-overrun: ellipsis - 长文本在适当位置换行或滚动
Spacing & Layout
间距与布局
- Consistent spacing scale is applied (not arbitrary padding values)
- Visual grouping through spacing: related items are closer, groups are separated
- Content doesn't touch container edges (adequate padding on all regions)
- Layout adapts when window is resized (no overlap, no hidden content)
- Minimum window size is set and prevents broken layouts
- 应用了一致的间距比例(无任意内边距值)
- 通过间距实现视觉分组:相关元素间距更近,组与组之间分隔开
- 内容未接触容器边缘(所有区域都有足够的内边距)
- 窗口调整大小时布局能自适应(无重叠、无隐藏内容)
- 设置了最小窗口尺寸,防止布局损坏
Interactivity
交互性
- All interactive elements have state
:hover - Focus indicators are visible and styled appropriately
- Disabled states are visually distinct (reduced opacity)
- Clickable items use hand cursor ()
-fx-cursor: hand - Interactive targets are at least 32×32px
- Tooltips on icon-only buttons
- 所有交互元素都有状态
:hover - 焦点指示器可见且样式合适
- 禁用状态在视觉上有明显区别(降低透明度)
- 可点击元素使用手型光标()
-fx-cursor: hand - 交互目标尺寸至少为32×32px
- 仅含图标的按钮有工具提示
Consistency
一致性
- All buttons of the same type look identical
- Form fields have uniform height, border radius, and padding
- Spacing between form labels and fields is uniform
- Card/panel styling is consistent across all views
- One primary action style per view (visual hierarchy is clear)
- 同一类型的所有按钮外观相同
- 表单字段的高度、边框半径和内边距统一
- 表单标签与字段之间的间距统一
- 所有视图中的卡片/面板样式一致
- 每个视图只有一种主要操作样式(视觉层级清晰)
14. Common Patterns & Anti-Patterns
14. 常见模式与反模式
Patterns (Do This)
推荐模式(应遵循)
Token-based design — Define all visual values (colors, sizes, radii, spacing) as looked-up
colors on . Makes themes trivial and ensures consistency.
.rootLayered backgrounds for depth — Use multiple values with
to create border and shadow effects. Performs better than .
-fx-background-color-fx-background-insets-fx-effectStyle class composition — Give controls multiple style classes that combine:
xml
<Button styleClass="button, primary, large" text="Submit" />css
.large { -fx-padding: 12px 24px; -fx-font-size: -fx-font-size-lg; }CSS-only states — Use pseudo-classes and looked-up colors to express all states in CSS.
Add/remove style classes for application states (, , ).
.error.success.loadingConsistent border radius — Pick 2–3 values and use them everywhere:
css
.root {
-fx-radius-sm: 4px;
-fx-radius-md: 8px;
-fx-radius-lg: 12px;
-fx-radius-full: 100px; /* for pills and circles */
}基于令牌的设计——在上定义所有视觉值(颜色、尺寸、圆角、间距)为查找颜色。使主题切换变得简单,并确保一致性。
.root分层背景实现深度——使用多个值结合创建边框和阴影效果。性能优于。
-fx-background-color-fx-background-insets-fx-effect样式类组合——为控件添加多个样式类进行组合:
xml
<Button styleClass="button, primary, large" text="Submit" />css
.large { -fx-padding: 12px 24px; -fx-font-size: -fx-font-size-lg; }纯CSS状态——使用伪类和查找颜色在CSS中表达所有状态。为应用状态(, , )添加/移除样式类。
.error.success.loading一致的边框半径——选择2-3个值并在各处使用:
css
.root {
-fx-radius-sm: 4px;
-fx-radius-md: 8px;
-fx-radius-lg: 12px;
-fx-radius-full: 100px; /* for pills and circles */
}Anti-Patterns (Avoid This)
反模式(应避免)
Inline styles in Java — creates unmaintainable,
unthemeable UI. Use style classes instead.
node.setStyle("-fx-background-color: red")Overriding per control — Changing on individual controls cascades
unpredictably through Modena's derived colors. Use specific properties instead.
-fx-base-fx-base-fx-effect: dropshadow(...)Ignoring Modena defaults — Fighting the default stylesheet causes inconsistencies. Either
commit to a full custom theme that resets all controls, or work within Modena's structure.
AnchorPanePixel-perfect fixed layouts — JavaFX runs on varying screen sizes and DPI settings. Design
with flexible sizing and test at different window sizes.
Java中的内联样式——会创建难以维护、无法主题化的UI。改用样式类。
node.setStyle("-fx-background-color: red")为单个控件覆盖——在单个控件上修改会导致Modena派生颜色出现不可预测的级联变化。改用特定属性。
-fx-base-fx-base到处使用——阴影效果性能开销大。使用背景颜色分层实现卡片边框;仅在对话框和弹出框中使用实际效果。
-fx-effect: dropshadow(...)忽略Modena默认样式——与默认样式表对抗会导致不一致。要么完全自定义主题重置所有控件,要么在Modena的结构内进行设计。
所有布局都用——会创建刚性、非响应式布局。优先使用带有增长优先级的VBox/HBox,使用BorderPane构建页面结构,使用GridPane构建表单。
AnchorPane像素级完美的固定布局——JavaFX运行在不同的屏幕尺寸和DPI设置下。设计时应使用灵活的尺寸,并在不同窗口尺寸下测试。
Official References
官方参考
- JavaFX CSS Reference Guide (v26) — Complete list of all CSS properties, types, and pseudo-classes per control
- Introduction to FXML (v26) — Markup language for defining JavaFX scene graphs declaratively
- JavaFX API Documentation (v26) — Full Javadoc for all JavaFX modules
- JavaFX CSS Reference Guide (v11) — Reference for older LTS version compatibility
- OpenJFX Home — Downloads, community projects, and getting started guides
- Scene Builder — Visual FXML editor for layout design
- JavaFX CSS参考指南(v26) ——所有控件的CSS属性、类型和伪类的完整列表
- FXML简介(v26) ——用于声明式定义JavaFX场景图的标记语言
- JavaFX API文档(v26) ——所有JavaFX模块的完整Javadoc
- JavaFX CSS参考指南(v11) ——旧版LTS版本兼容性参考
- OpenJFX官网——下载、社区项目和入门指南
- Scene Builder——用于布局设计的可视化FXML编辑器