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 - 後臺初始化
CefAppManager、App - 隱式初始化
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打開流程型彈窗 - 偏功能邏輯驅動,但會影響彈窗行爲和交互體驗
Cookie 登錄窗口¶
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.javasrc/test/java/b/test/LoadingDemo.javasrc/test/java/b/test/LafTest.java
用途:
- 快速驗證標題欄佈局方案
- 快速驗證 loading 視覺效果
- 快速驗證 FlatLaf 配置是否符合預期
如果我們要嘗試新的標題欄佈局或 loading 細節,建議先在這些 demo 上驗證,再合進主代碼。
現有 UI 改造優先級¶
建議按照下面順序推進:
MainFrameTitleBarMainFrameGlobalLoadingJcefBrowserDialog/ 登錄類彈窗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.javasrc/main/java/b/MainFrame.javasrc/test/java/b/test/FlatLafCustomTitleDemo.java
如果下一步改加載態:
src/main/java/b/ui/GlobalLoading.javasrc/test/java/b/test/LoadingDemo.java
如果下一步改啓動頁:
src/main/java/b/ui/SplashScreen.javasrc/main/java/b/Launcher.java
如果下一步改彈窗體系:
src/main/java/b/ui/JcefBrowserDialog.javasrc/main/java/b/ui/OpenGetCookieWindowAction.javasrc/main/java/b/ui/OpenM3u8DialogAction.java
我們接下來可以直接怎麼做¶
推薦從下面三種方式裏選一種進入:
- 直接重做
MainFrameTitleBar的佈局和視覺 - 先統一
GlobalLoading + JcefBrowserDialog的彈窗和遮罩風格 - 先抽一層 Swing 設計 token,再逐個替換現有硬編碼顏色和尺寸
如果目標是最快看到成品效果,建議先從 MainFrameTitleBar 開始。