跳转至

Swing UI 开发准备地图

本文档用于给 TG-FF 的 Java Swing UI 调整做快速对齐,重点是:

  • 现有 Swing 结构在哪些文件
  • 主题、标题栏、弹窗、加载态分别怎么接入
  • 调整 UI 时哪些地方优先动,哪些地方要谨慎

当前技术基线

  • 构建:Maven
  • Java:21
  • Look and Feel:FlatLaf 3.7
  • 主界面容器:Swing JFrame
  • 主内容区:JCEF 浏览器组件
  • UI 形态:Swing 外壳 + 自定义标题栏 + JCEF 页面

这意味着我们现在要调整的不是传统“纯 Swing 后台管理系统”,而是一个带原生窗口定制、重度嵌入浏览器组件的桌面壳层。

关键入口文件

启动与全局主题

  • src/main/java/b/Launcher.java

职责:

  • 启动时调用 setupFlatLaf()
  • 先显示 SplashScreen
  • 后台初始化 CefAppManagerApp
  • 隐式初始化 MainFrame
  • 等待首屏资源和前端 ready 后再显示主窗口

关键信息:

  • macOS 使用 FlatMacLightLaf
  • Windows/Linux 使用 FlatIntelliJLaf
  • 全局抗锯齿和字体渲染在这里设置

如果要做全局视觉基调调整,优先从这里看主题初始化是否要补全统一 token 或全局 UIManager 配置。

主窗口壳层

  • src/main/java/b/MainFrame.java

职责:

  • 创建主 JFrame
  • 配置 Java 标题栏窗口属性
  • MainFrameTitleBar 和 JCEF 内容区拼装到一起
  • 管理窗口尺寸、显示、焦点、托盘、标题栏数据同步

当前主窗口结构大致是:

JFrame -> resizeLayer -> contentPanel -> [MainFrameTitleBar + browserHolder(JCEF)]

当前窗口约束:

  • 默认尺寸:1336 x 900
  • 最小尺寸:1300 x 850
  • 最大尺寸:1336 x 1000

如果后面我们改整体布局、边距、窗口气质,这里会是第一落点。

自定义标题栏

  • src/main/java/b/ui/MainFrameTitleBar.java

职责:

  • 自定义标题栏 UI
  • 顶部状态胶囊:会员、代理、网络、上传下载速率
  • 主题切换后的颜色重绘
  • 标题栏交互事件回传给前端
  • macOS/Windows 不同标题栏行为适配

当前特点:

  • 高度常量:42
  • 内置 LIGHT_THEME / DARK_THEME
  • 颜色目前主要是代码里硬编码的 palette
  • 交互通过 ActionPayload 回给前端桥

如果这轮改造是“更现代、更统一、更高级”的标题栏,这个文件会是最高优先级。

启动页

  • src/main/java/b/ui/SplashScreen.java

职责:

  • 启动渐变背景页
  • 图标、标题、状态文本、进度条
  • 启动期错误展示

当前特点:

  • 视觉是偏浅蓝渐变
  • 进度条和文案已做过定制
  • 主要用于启动阶段,不参与主界面日常交互

如果本轮 UI 只聚焦主界面,这里优先级低于标题栏和弹窗。

全局加载遮罩

  • src/main/java/b/ui/GlobalLoading.java

职责:

  • JFrame / JDialog / Window 提供 loading 遮罩
  • 兼容 JCEF 这种 heavyweight 组件

关键点:

  • 普通场景走 glassPane
  • Window 场景可走透明 JDialog 叠层,避免被 JCEF 压住
  • 视觉由半透明蒙层 + 中央 spinner + pill 文案组成

这个文件是后续统一“加载态风格”的重要位置。

次级 UI 入口

通用浏览器弹窗

  • src/main/java/b/ui/JcefBrowserDialog.java

用途:

  • 可复用的 JDialog + JCEF
  • 登录、抓取、辅助操作类弹窗都可能复用它

如果我们想统一弹窗边距、圆角、标题、默认尺寸、遮罩体验,这里值得单独整理。

M3U8 相关弹窗动作

  • src/main/java/b/ui/OpenM3u8DialogAction.java

特点:

  • 通过 JcefBrowserDialog 打开流程型弹窗
  • 偏功能逻辑驱动,但会影响弹窗行为和交互体验
  • src/main/java/b/ui/OpenGetCookieWindowAction.java

特点:

  • 内部有一个 BrowserFrame extends JFrame
  • 属于独立窗口,不完全走主框架壳层

这类窗口后面如果要统一风格,最好收敛到统一弹窗/窗口基类策略。

系统托盘

  • src/main/java/b/ui/SystemTrayManager.java

虽然不是核心视觉区,但它影响窗口可见性、最小化、退出路径。涉及窗口行为时要一起确认。

现成可参考的 UI Demo

  • src/test/java/b/test/FlatLafCustomTitleDemo.java
  • src/test/java/b/test/LoadingDemo.java
  • src/test/java/b/test/LafTest.java

用途:

  • 快速验证标题栏布局方案
  • 快速验证 loading 视觉效果
  • 快速验证 FlatLaf 配置是否符合预期

如果我们要尝试新的标题栏布局或 loading 细节,建议先在这些 demo 上验证,再合进主代码。

现有 UI 改造优先级

建议按照下面顺序推进:

  1. MainFrameTitleBar
  2. MainFrame
  3. GlobalLoading
  4. JcefBrowserDialog / 登录类弹窗
  5. SplashScreen

原因:

  • 标题栏最能直接拉高整体质感
  • 主窗口边距和层级决定整体观感
  • loading 和弹窗会决定“完成度”
  • 启动页影响相对次要

当前 UI 机制里的几个关键限制

1. JCEF 是 heavyweight 组件

这会带来两个直接影响:

  • 普通 Swing 叠层不一定能盖住它
  • 遮罩、弹窗、拖拽、焦点处理都要更小心

因此:

  • 遮罩相关优先沿用 GlobalLoading 现有思路
  • 不要想当然把普通 JPanel 盖在浏览器上就结束

2. 主题并没有完全 token 化

当前标题栏颜色主要集中在 MainFrameTitleBar 内部静态 palette,其他地方也有各自硬编码颜色。

这意味着:

  • 小改可以直接改局部 palette
  • 如果要做系统级统一风格,建议抽一层 Swing 主题 token

3. 标题栏不只是视觉组件

MainFrameTitleBar 同时承担:

  • 状态展示
  • 按钮交互
  • 与前端桥通信
  • 窗口 caption / drag 区域控制

所以改它时不能只看样式,还要保住:

  • 拖拽区域
  • macOS 按钮占位
  • Windows 标题栏属性同步
  • 事件锚点坐标回传

4. 跨平台差异已经存在

现在代码已经显式区分:

  • macOS 标题栏属性
  • Windows/Linux 的 FlatLaf window decorations
  • 托盘在 macOS 默认关闭

所以 UI 修改要默认带着“至少 macOS + Windows”两个维度思考。

建议的本轮改造方法

第一阶段:统一视觉语言

建议先统一这些基础项:

  • 标题栏高度、内边距、间距
  • 主色、文字色、弱化色、状态色
  • 胶囊圆角、边框、阴影
  • 图标尺寸和按钮 hit area
  • loading 遮罩透明度和文案样式

第二阶段:统一窗口与弹窗风格

建议处理:

  • 主窗口边距与内容留白
  • JDialog/JFrame 弹窗默认尺寸和位置策略
  • 浏览器弹窗标题和关闭体验
  • 登录/抓取窗口是否需要统一外壳

第三阶段:整理代码结构

当视觉稳定后,可以再考虑:

  • SwingThemeTokens
  • 抽通用 Pill / IconButton / StatusDot
  • 收敛重复颜色和尺寸常量
  • 收敛弹窗基类或窗口配置工具

实战时建议先看的文件组合

如果下一步直接开始改标题栏:

  • src/main/java/b/ui/MainFrameTitleBar.java
  • src/main/java/b/MainFrame.java
  • src/test/java/b/test/FlatLafCustomTitleDemo.java

如果下一步改加载态:

  • src/main/java/b/ui/GlobalLoading.java
  • src/test/java/b/test/LoadingDemo.java

如果下一步改启动页:

  • src/main/java/b/ui/SplashScreen.java
  • src/main/java/b/Launcher.java

如果下一步改弹窗体系:

  • src/main/java/b/ui/JcefBrowserDialog.java
  • src/main/java/b/ui/OpenGetCookieWindowAction.java
  • src/main/java/b/ui/OpenM3u8DialogAction.java

我们接下来可以直接怎么做

推荐从下面三种方式里选一种进入:

  • 直接重做 MainFrameTitleBar 的布局和视觉
  • 先统一 GlobalLoading + JcefBrowserDialog 的弹窗和遮罩风格
  • 先抽一层 Swing 设计 token,再逐个替换现有硬编码颜色和尺寸

如果目标是最快看到成品效果,建议先从 MainFrameTitleBar 开始。