我正在尝试在我的Java Swing应用程序中调试一些与焦点有关的问题.有些时候,一些组件似乎正在抓住焦点,我无法确定代码中发生的位置.
我试过了
>使用KeyboardFocusManager(用于focusOwner)的Vetoablechangelistener.这给我提供了哪些组件丢失并获得焦点的信息,但是它并没有帮助我指出在代码中哪些重点被要求.
>自定义KeyboardFocusManager.但是,我也可以在收到事件时进行干预.到那时,对requestFocus的调用的调用堆栈已经丢失了.
>自定义EventQueue.但是我也可以介入从EDT调用的dispatchEvent方法.调用堆栈再次丢失(有趣的是没有调用postEvent(AWTEvent)).
题:
当我调用requestFocusInWindow时,我正在寻找的是调用堆栈.是否可以获取此信息.也许,如果我可以重新定义用于在EventQueue中发布事件的方法,那么我可以打印堆栈转储.但是EventQueue.postEvent(AWTEvent)不会被调用.
任何人都可以提出一个解决方案,这将有助于我在调用requestFocus或requestFocusInWIndow时获取堆栈的状态?
解决方法
幸运的是,如果你使用的是Sun JRE,那么你可以插入一个代码,但它不漂亮:
Component.requestFocus()调用静态KeyboardFocusManager.setMostRecentFocusOwner(Component),它更新一个名为mostRecentFocusOwners的私有静态Map.
因此,如果您可以使用反射访问静态Map,则可以使用将调用跟踪到put方法的转发Map替换:
import com.google.common.collect.ForwardingMap; // ... Field mrfoField = KeyboardFocusManager.class.getDeclaredField("mostRecentFocusOwners"); mrfoField.setAccessible(true); final Map delegate = (Map) mrfoField.get(null); Map mrfo = new ForwardingMap() { public Object put(Object key,Object value) { new Throwable().printstacktrace(); return super.put(key,value); } protected Map delegate() { return delegate; } }; mrfoField.set(null,mrfo);
这将捕获requestFocus的调用并给你堆栈跟踪.
原文地址:https://www.jb51.cc/java/121168.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。