Posted on 2008-10-29 16:51
英雄 阅读(1241)
评论(0) 编辑 收藏
Java Focus实现纪要三
特别注意:按java给出的Focus实现规范,jre1.7保证实现如下几点:
1. Focus_Gained,Focus_Lost事件的序列。即如果在EDT中,应用程序查询currentFocusOwner,=A,此后=B,则中间一定按顺序收到A Lost,B Gain.这主要通过DefaultKeyboardFocusManager.dispatchEvent时,尤其是处理Gained(PreparedFocusGained)时,如果发现currentFocusOwner!=null,说明尚未得到Lost,则会主动生成一个Lost发布,处理后继续处理Gained。
2. 如果是在同一个重量级组件间做轻量级组件间切换,每一个focus event实例上可以获取到准确的opposite,source.这主要通过DefaultKeyboardFocusManager.dispatchEvent和KeyboardFocusManager.retargetEvent时,主动控制纠正可能的不准确的source,opposite。
3. Focus Event支持temporary应用,尤其体现在当整个window失去焦点,当再次获取焦点时将恢复此window的最后聚焦组件。应用程序查询focus event.isTemporary==true时,则可以确信该组件按既有逻辑很快将恢复焦点。这主要通过DefaultKeyboardFocusManager.dispatchEvent和KeyboardFocusManager.retargetEvent时,对temporary做了充分的考虑控制。
4. KeyEvent的处理符合规范流程:
a. 根据request时间戳缓存。
b. 解除缓存时首先KeyboardFocusManager.isProxyActive(KEYEVENT),考虑是否交给本地系统代理处理。
c. 否则KeyboardFocusManager.注册keyEventDispatchers接手处理。
d. 发布该keyevent给对应component进行处理,其中分为如下阶段:
1. Allow the Toolkit to pass this to AWTEventListeners.注册在toolkit下的AWTEventListeners得到处理。
2. KeyboardFocusManager.processKeyEvent用来处理焦点遍历(TAB等)。
3. Pre-process any special events before delivery。对KEY_PRESSED,KEY_RELEASED,组件的容器有机会preProcessKeyEvent。
4. 组件的对应Key(Press,Typed,~~)Listener进行处理。
e. KeyboardFocusManager.注册keyEventPostProcessors接手处理。
f. 组件peer得到机会处理。
在其上1,2,3点的实现中,Jre1.7版本充分考虑了跨平台性:比如Windows系统,如果仅仅是拖动滚动条是不会发出FocusEvent,而其他系统就会发出temporary的FocusEvent;有些系统在重量级对等体间切换可以提供准确的opposite,但是有些系统则不提供。而jre1.7在实现上融合了各个系统的情况,给出了全面判断并针对性地处理,保证了跨平台的Focus规范表现。