How can I get the window handle (hWnd) for a Stage in JavaFX?

浪子不回头ぞ 提交于 2019-11-29 05:06:12

Here's a JavaFX2 version (uses Stage rather than Window):

private static Pointer getWindowPointer(Stage stage) {
    try {
        TKStage tkStage = stage.impl_getPeer();
        Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow" );
        getPlatformWindow.setAccessible(true);
        Object platformWindow = getPlatformWindow.invoke(tkStage);
        Method getNativeHandle = platformWindow.getClass().getMethod( "getNativeHandle" );
        getNativeHandle.setAccessible(true);
        Object nativeHandle = getNativeHandle.invoke(platformWindow);
        return new Pointer((Long) nativeHandle);
    } catch (Throwable e) {
        System.err.println("Error getting Window Pointer");
        return null;
    }
}
Xanatos

The following method shows how you can get a native window handle (hWnd) for a JavaFX Stage (or Window) and then store it in a JNA Pointer object:

private static Pointer getWindowPointer(javafx.stage.Window window) {
    Pointer retval = null;
    try {
        Method getPeer = window.getClass().getMethod("impl_getPeer");
        final Object tkStage = getPeer.invoke(window);
        Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow");
        getPlatformWindow.setAccessible(true);
        final Object platformWindow = getPlatformWindow.invoke(tkStage);
        Method getNativeHandle = platformWindow.getClass().getMethod("getNativeHandle");
        retval = new Pointer((Long) getNativeHandle.invoke(platformWindow));
    } catch (Throwable t) {
        System.err.println("Error getting Window Pointer");
        t.printStackTrace();
    }
    return retval;
}

This solution is fragile and generally undesirable, since it uses reflection to access a bunch of private methods. But it gets the job done. Hopefully Oracle will eventually give us direct access to native window handles so we don't have to do this.

Of course, this code only works when you're running on MS Windows. Also, I've only tried it out with early release builds of JavaFX 8 (but I suspect it will work fine on JavaFX 2 as well. EDIT: looks like it doesn't work in JavaFX 2.)

com.sun.glass.ui.Window.getWindows.get(0).getNativeWindow

//

com.sun.glass.ui.Window.getFocusedWindow.getNativeWindow

Add a dependency on JNA:

<dependency>
  <groupId>net.java.dev.jna</groupId>
  <artifactId>jna-platform</artifactId>
  <version>5.3.1</version>
</dependency>

Then give your Stage a distinct title ("MyStage" in this example), and then get the Window ID like this:

WinDef.HWND hwnd = User32.INSTANCE.FindWindow(null, "MyStage");

long wid = Pointer.nativeValue(hwnd.getPointer());

This will work on Windows regardless of JavaFX version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!