如何在JavaFX中调用WinAPI并自定义Stage标题栏?
解决方案方向
1. 放弃完全无装饰窗口,保留系统框架做自定义
别直接用StageStyle.UNDECORATED或TRANSPARENT,这种方式会彻底移除系统窗口框架,直接丢失缩放、分屏、任务栏显示这些原生功能。优先用StageStyle.UNIFIED(JavaFX 8及以上支持),它能让标题栏和内容区域融合,既能改标题栏背景色,又能完整保留所有系统窗口功能。如果要更深度自定义(比如换按钮样式),就通过JNA调用WinAPI在原生框架基础上修改,而非完全替换。
2. 用JNA调用WinAPI的具体操作步骤
- 引入JNA依赖:在IntelliJ的Maven或Gradle配置里加JNA核心和平台包:
Maven配置:
Gradle配置:<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>implementation 'net.java.dev.jna:jna:5.13.0' implementation 'net.java.dev.jna:jna-platform:5.13.0' - 获取JavaFX窗口的原生句柄:
import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef.HWND; import javafx.stage.Stage; import com.sun.glass.ui.Window; public static HWND getHWND(Stage stage) { Window window = stage.getPeer(); return new HWND(window.getNativeHandle()); } - 修改标题栏颜色:调用WinAPI的
DwmSetWindowAttribute设置标题栏背景色:import com.sun.jna.platform.win32.Dwmapi; import com.sun.jna.platform.win32.WinDef.DWORD; public static void setTitleBarColor(Stage stage, int rgb) { HWND hwnd = getHWND(stage); // 转成WinAPI用的BGR格式 int bgr = ((rgb & 0xFF) << 16) | (rgb & 0xFF00) | ((rgb & 0xFF0000) >> 16); DWORD color = new DWORD(bgr); Dwmapi.INSTANCE.DwmSetWindowAttribute(hwnd, Dwmapi.DWMWA_CAPTION_COLOR, color, DWORD.SIZE); } - 自定义标题栏按钮:先隐藏原生按钮,再在JavaFX界面加自定义按钮,通过JNA调用WinAPI实现对应功能:
// 最小化窗口 public static void minimizeWindow(HWND hwnd) { User32.INSTANCE.ShowWindow(hwnd, User32.SW_MINIMIZE); } // 最大化窗口 public static void maximizeWindow(HWND hwnd) { User32.INSTANCE.ShowWindow(hwnd, User32.SW_MAXIMIZE); } // 关闭窗口 public static void closeWindow(HWND hwnd) { User32.INSTANCE.SendMessage(hwnd, User32.WM_CLOSE, null, null); }
3. 保留系统功能的核心注意点
- 全程保留系统窗口框架,所有自定义操作基于原生窗口句柄修改,这样窗口会正常出现在任务栏、系统窗口选择菜单里,缩放、分屏、全屏这些功能也不会失效。
- 注意Windows版本兼容性,部分DWM API在Win10和Win11上的表现有差异,测试时要针对目标系统调整参数。
4. 偷懒方案:用第三方JavaFX库
不想自己写WinAPI调用的话,直接用现成的第三方库,比如JMetro或ControlsFX。它们提供了封装好的自定义标题栏组件,支持改颜色、换按钮样式,还能完整保留原生窗口功能,不用自己折腾底层调用。
内容的提问来源于stack exchange,提问作者Krowley1661
相关产品推荐
相关产品推荐

