Posted on 2008-10-29 16:51
英雄 閱讀(1245)
評論(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規范表現。