加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

在Java中进行焦点调试

发布时间:2020-12-14 05:50:50 所属栏目:Java 来源:网络整理
导读:问题: 我正在尝试在我的Java Swing应用程序中调试一些与焦点有关的问题.有些时候,一些组件似乎正在抓住焦点,我无法确定代码中发生的位置. 我试过了 使用KeyboardFocusManager(用于focusOwner)的VetoableChangeListener.这给我提供了哪些组件丢失并获得焦点
问题:

我正在尝试在我的Java Swing应用程序中调试一些与焦点有关的问题.有些时候,一些组件似乎正在抓住焦点,我无法确定代码中发生的位置.

我试过了

>使用KeyboardFocusManager(用于focusOwner)的VetoableChangeListener.这给我提供了哪些组件丢失并获得焦点的信息,但是它并没有帮助我指出在代码中哪些重点被要求.
>自定义KeyboardFocusManager.但是,我也可以在收到事件时进行干预.到那时,对requestFocus的调用的调用堆栈已经丢失了.
>自定义EventQueue.但是我也可以介入从EDT调用的dispatchEvent方法.调用堆栈再次丢失(有趣的是没有调用postEvent(AWTEvent)).

题:

当我调用requestFocusInWindow时,我正在寻找的是调用堆栈.是否可以获取此信息.也许,如果我可以重新定义用于在EventQueue中发布事件的方法,那么我可以打印堆栈转储.但是EventQueue.postEvent(AWTEvent)不会被调用.

任何人都可以提出一个解决方案,这将有助于我在调用requestFocus或requestFocusInWIndow时获取堆栈的状态?

解决方法

看来他们(太阳)真的不想让你这样做.乍一看,这个路径中似乎没有任何可以轻易被覆盖的虚拟方法,而不是在EventQueue中(PostEvent仅用于invokeLater和从应用程序代码合成事件),也没有在KeyboardFocusManager中使用(如您所见,调度循环稍后调用可覆盖的方法.)

幸运的是,如果你使用的是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的调用并给你堆栈跟踪.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读