看来他们(太阳)真的不想让你这样做.乍一看,这个路径中似乎没有任何可以轻易被覆盖的虚拟方法,而不是在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的调用并给你堆栈跟踪.