如何从Java Swing的JFrame中获取窗口句柄(HWND)?
获取Java Swing JFrame的HWND窗口句柄(替代废弃的getPeer()方法)
完全可行,你遇到的问题是因为getPeer()属于Sun/Oracle JDK的内部非公开API,在高版本JDK中已经被移除,导致抛出NoSuchMethodError。下面提供两种可靠的替代方案:
方案一:使用JNA(推荐)
JNA(Java Native Access)是官方推荐的原生API访问库,无需编写JNI代码,就能直接调用Windows系统API,兼容性和稳定性远优于依赖内部JDK API的方式。
实现代码:
import com.sun.jna.Native; import com.sun.jna.platform.win32.WinDef.HWND; import javax.swing.*; import java.awt.*; public class HWndUtil { public static long getHWndValue(Window window) { // 获取窗口的原生指针并转换为HWND HWND hwnd = new HWND(Native.getComponentPointer(window)); // 转换为long类型,用于传入你的REST API return Native.getPointerAddress(hwnd.getPointer()); } public static void main(String[] args) { JFrame frame = new JFrame("测试窗口"); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); long hwnd = getHWndValue(frame); System.out.println("窗口HWND值:" + hwnd); } }
前置准备:
引入JNA依赖(如使用Maven,添加jna和jna-platform依赖到pom.xml;手动管理则下载对应jar包)。
方案二:使用反射(仅应急用)
如果暂时无法引入JNA,可以通过反射调用JDK内部的隐藏方法,但这种方式依赖JDK具体实现,不同版本或厂商的JDK可能不兼容,未来有失效风险。
实现代码:
import javax.swing.*; import java.awt.*; import java.lang.reflect.Method; public class HWndReflectionUtil { public static long getHWndValue(Window window) { try { // 反射调用getPeer()方法 Method getPeerMethod = Component.class.getDeclaredMethod("getPeer"); getPeerMethod.setAccessible(true); Object peer = getPeerMethod.invoke(window); // 反射调用getHWnd()方法 Method getHWndMethod = peer.getClass().getDeclaredMethod("getHWnd"); getHWndMethod.setAccessible(true); return (long) getHWndMethod.invoke(peer); } catch (Exception e) { e.printStackTrace(); return 0; } } public static void main(String[] args) { JFrame frame = new JFrame("测试窗口"); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); long hwnd = getHWndValue(frame); System.out.println("窗口HWND值:" + hwnd); } }
注意事项:
- 必须确保调用
getHWndValue()时,JFrame已经执行了setVisible(true),否则窗口未完成初始化,无法获取有效HWND。 - 优先选择JNA方案,避免依赖JDK内部API带来的兼容性问题。
内容的提问来源于stack exchange,提问作者DecentWig
相关产品推荐
相关产品推荐

