<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Focus實現(xiàn)紀要二

    Posted on 2008-10-26 17:20 英雄 閱讀(1347) 評論(0)  編輯  收藏
     

    Java Focus實現(xiàn)紀要二

    1.       Jre1.7版本中,KeyboardFocusManagerDefaultKeyboardFocusManager這兩個類,Component, WComponentPeer類一起完成了focus的主要邏輯實現(xiàn)。

    DefaultKeyboardFocusManager是前者的系統(tǒng)默認實現(xiàn)。其單例注冊在appcontext,如果需要,程序員可以替代它,以擴展focus的邏輯實現(xiàn)。

    appcontext.put(KeyboardFocusManager.class, new SelfKeyboardFocusManager());

    2.       Component中提供了requestFocus方法。而各個組件在初始化時都會安裝默認的Listener。當這些Listener收到適當?shù)氖录ㄖ螅ū热?/span>mouse_press)即會調(diào)用這個方法。該方法首先判斷該組件是否focusable,組件所依托窗口是否focusable,當前聚焦組件的InputVerifier是否驗收輸入等等,判斷通過后請求重量級組件容器的peer.requestFocusWComponentPeer中提供該requestFocus方法。該方法首先調(diào)用native processSynchronousLightweightTransfer,其會調(diào)用KeyboardFocusManager .processSynchronousLightweightTransferr,作用是如果當前request組件的重量級組件容器正對應(yīng)當前底層系統(tǒng)的聚焦組件,而且當前沒有任何切換焦點的heavyweightRequests,這時將直接切換focus變量KeyboardFocusManager.focusOwner

    如果上述調(diào)用沒有順利完成并返回true,則會調(diào)用native _requestFoucs。該方法會調(diào)用KeyboardFocusManager .shouldNativelyFocusHeavyweight,其作用就是完成request登記,并在登記時間戳以正確緩存處理后續(xù)進入EDTKeyevent處理。

    Request登記的結(jié)構(gòu)為KeyboardFocusManager.heavyweightRequests=

    LinkedList< HeavyweightFocusRequest >

    -- HeavyweightFocusRequest{

    Component heavyweight;

    LinkedList<LightweightFocusRequest> lightweightRequests登記方式分為3:

    a. 如果發(fā)出requestFocus的組件的重量級組件容器正對應(yīng)當前底層系統(tǒng)的聚焦組件,而且當前沒有任何切換焦點的heavyweightRequest,則增加一個heavyweightRequest并向Post-Qqeue post focus-event

    b. 如果發(fā)出requestFocus組件的重量級組件容器不對應(yīng)當前底層系統(tǒng)的聚焦組件,而且當前沒有任何切換焦點的heavyweightRequest;或者當前存在切換焦點的heavyweightRequest,而最后一個heavyweightRequest. Heavyweight!=當前request組件的重量級組件容器,則要增加一個heavyweightRequest,并同步通知底層系統(tǒng)進行重量級對等組件的focus切換

    c. 如果當前存在切換焦點的heavyweightRequest,而且最后一個heavyweightRequest. Heavyweight==當前requestFocus的組件的重量級組件容器,則直接在request.lightweightRequests追加一個LightweightFocusRequest

    3.       EDT在逐個處理AWTEvent時,委托給EventQueue.dispatchEvent,繼而委托給Component. dispatchEventImpl,該方法順序執(zhí)行下面的代碼片段:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·

    /* focusManagerIsDispatching標志了該event;如果==true意味著該event不會交由KeyboardManager進行retargetdispatch。而這兩個動作主要完成的功能就是刷新java的全局focus變量。因此可以想象focusManagerIsDispatching==trueFocus_eventfocus發(fā)生切換后的event,而focusManagerIsDispatching==false的是PrepareFocusEvent*/

                if (!e.focusManagerIsDispatching) {//----------PrepareFocusEvent

                // Invoke the private focus retargeting method which provides

                // lightweight Component supportF

                /*通過retargetFocus,處理之前注冊的request請求,最終激發(fā)出合適的CausedFocusEvent,交給下面的dispatch.

     */

                if (e.isPosted) {

                    e = KeyboardFocusManager.retargetFocusEvent(e);

                    e.isPosted = true;

                }

                // Now, with the event properly targeted to a lightweight

                // descendant if necessary, invoke the public focus retargeting

                // and dispatching function

    /*通過dispatch給注冊的DefaultKeyboardFocusManager,最終更新了java的全局focus變量

     */

                if (KeyboardFocusManager.getCurrentKeyboardFocusManager().

                    dispatchEvent(e))

                {

                    return;

                }

            }

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·

    4.       總之:

    a. 輕量級組件的Mouse_Press ListenerrequestFocusrequest通過必要條件檢查后會在KeyboardFocusManager.heavyweightRequests緩存列表登記,同時在一個列表中登記一個時間戳marker=當前系統(tǒng)時間。

    b. 每一個KeyEvent都有一個發(fā)生時間when,這個發(fā)生時間認為是AWT-Windows loop底層event形成KeyEvent的時間。EDT在調(diào)用KeyboardFocusManager dispatchEvent處理一個KeyEvent時只要發(fā)現(xiàn)when晚于時間戳緩存列表中登記的第一個時間戳,就充分說明這是在某焦點切換請求發(fā)出后發(fā)生的鍵盤事件,則不應(yīng)該將這個KeyEvent target到當前全局focus變量,因而這時暫將此KeyEvent緩存在另一個列表。

    c. 根據(jù)前面的分析,在requestFocus時有3種情況,一種是新增heavyweightRequest,同時postpost-queue一個FocusEvent,一種是新增heavyweightRequest,同時因為要求底層系統(tǒng)切換重量級對等體而awt-loop到一個FocusEvent,這兩種情況的request都在列表中期待對應(yīng)FocusEvent到來再切換焦點。從登記時間戳開始,被awt-loop到的KeyEvent進入EDT時都將緩存下來,而一段時間后當期待的FocusEventpost-queue進入event-queue并要在EDT中處理時,有充分的條件可以判斷出此后再進入EDTKeyEvent,都至少是request登記時間戳后發(fā)生的,則這時可以完成此request-刪除該heavyweightRequest緩存條目,做focus實際切換,并將緩存的KeyEvent 及時間戳記錄處理掉。而第3種情況是在requestFocus時可以在最末一個heavyweightRequest上直接追加LightWeightReuquest,那么當該heavyweightRequest期待的FocusEvent到來時,按前面所述處理完該request,再將后續(xù)LightWeightRequest保存引用到一個全局變量KeyboardFocusManager.currentLightweightRequests,再將此刻為止awt-loop至的post-queue的所有event完全flushevent-queue,再把一個要求循環(huán)處理所有currentLightweightRequests指向的LightWeightRequestsInvocationEvent post event-queue之后。這樣當EDT開始處理該InvocationEvent時,有充分的條件可以判斷出此后再進入EDTKeyEvent,都至少是最后一個后續(xù)LightWeightRequest登記時間戳后發(fā)生的,則這時只需按該InvocationEvent執(zhí)行即可,及逐個清理LightWeightRequest完成focus切換及處理時間戳和緩存KeyEvent。如果在循環(huán)處理過程中發(fā)生對某一個組件requestFocus調(diào)用,這時會根據(jù)處理之初currentLightweightRequests中是否只有單獨1request來確定能否processSynchronousLightweightTransferr即如果有多個,則這時禁止processSynchronousLightweightTransferr以防止破壞了切換焦點的順序。

    d. 重量級組件不需要在Mouse_Press Listener request Focus,當被進行Mouse Press時,底層系統(tǒng)分發(fā)一個Focus Event,當進入EDT處理時,在jre1.7中通過KeyboardFocusManager.retargetUnexpectedFocusEventretarget首先逐個剔除request后進行期待匹配(針對可能的底層分發(fā)-post-queue-event-queue中間環(huán)節(jié)Event的遺漏等例外情形),如果最后沒有一個request匹配,則直接形成CausedFocusEvent交給后繼dispatch完成焦點切換。更確切地說,對于jre1.7而言組件聚焦應(yīng)該都通過requestFocus完成切換,不通過該方式的聚焦切換在retarget時將歸屬到Unexpected被處理,而重量級組件的這種聚焦正好通過unexpected完成。

    5.       最后,個人認為jre1.7中存在一個可能的問題:每次dispatchEvent時都會在retargetFocusEventprocessCurrentLightweightRequests這樣不久破壞了4-c分析的時機邏輯了么?為什么要這樣呢?


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    主站蜘蛛池模板: 亚洲国产精品成人综合色在线| 亚洲国产免费综合| 在线观看免费精品国产| 男人免费视频一区二区在线观看| 免费无码国产在线观国内自拍中文字幕 | 亚洲精品第一综合99久久| 国产婷婷高清在线观看免费| 免费久久人人爽人人爽av| 亚洲一级特黄大片无码毛片 | 国产一区二区三区亚洲综合| 免费无码一区二区三区蜜桃大| WWW国产成人免费观看视频| 亚洲国产成人精品无码区在线秒播 | 亚洲综合久久一本伊伊区| 最近中文字幕mv免费高清视频8| 亚洲AV无码一区二区一二区| 亚洲av永久无码精品漫画 | 亚洲黄色免费在线观看| 亚洲第一网站免费视频| 亚洲成a人片在线播放| 精品视频免费在线| 亚洲免费在线视频| 最近中文字幕大全免费视频| 免费无遮挡无码视频在线观看| 亚洲蜜芽在线精品一区| 中文字幕精品无码亚洲字| 中文在线免费观看| 亚洲爆乳AAA无码专区| 亚洲人成在线观看| 在线观看亚洲成人| 性做久久久久免费看| 日韩视频在线精品视频免费观看| 国产免费高清69式视频在线观看| 亚洲私人无码综合久久网| 亚洲成a人片在线观看久| 中文字幕人成无码免费视频| 牛牛在线精品观看免费正| 亚洲精品日韩一区二区小说| 亚洲熟妇色自偷自拍另类| 亚洲Av无码精品色午夜 | 亚洲精品欧美综合四区|