You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaFX中调用WinAPI并自定义Stage标题栏?

解决方案方向

1. 放弃完全无装饰窗口,保留系统框架做自定义

别直接用StageStyle.UNDECORATED或TRANSPARENT,这种方式会彻底移除系统窗口框架,直接丢失缩放、分屏、任务栏显示这些原生功能。优先用StageStyle.UNIFIED(JavaFX 8及以上支持),它能让标题栏和内容区域融合,既能改标题栏背景色,又能完整保留所有系统窗口功能。如果要更深度自定义(比如换按钮样式),就通过JNA调用WinAPI在原生框架基础上修改,而非完全替换。

2. 用JNA调用WinAPI的具体操作步骤

  • 引入JNA依赖:在IntelliJ的Maven或Gradle配置里加JNA核心和平台包:
    Maven配置:
    <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>
    
    Gradle配置:
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:36:02