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

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

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

    xdingding  
    日歷
    <2009年10月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567
    統計
    • 隨筆 - 26
    • 文章 - 0
    • 評論 - 35
    • 引用 - 0

    導航

    常用鏈接

    留言簿(11)

    我參與的團隊

    隨筆分類

    隨筆檔案

    最新隨筆

    搜索

    •  

    積分與排名

    • 積分 - 31736
    • 排名 - 1335

    最新評論

    閱讀排行榜

    評論排行榜

     

    郁悶!同志們沒有留言,不知是寫的太差,何處需要改進,還是大家覺得對自己沒有用處.... 

    GEF源碼分析(四) GEF 消息轉義 ___ Tool的作用


    接著上一節:

    我們先解決如下問題:

    在界面操作過程中,我們希望面對的是邊框調整事件,圖形移動事件,或者是編輯文本事件,而不是原始的鼠標和鍵盤事件?

     

     

    術語定義:

    系統UI事件:        一般由某些計算機人機交互硬件發出信號,并且經操作系統理解后產生的事件,例如:原始的鼠標的移動、點擊和鍵盤的敲擊事件等。

    UI業務語義事件: 由系統UI事件和其它UI業務語義事件觸發,由UI業務代碼理解后產生的事件(操作系統不可理解,同時無任何領域的業務語義),如2D圖形的尺寸調整,2D圖形的點擊,2D圖形的移動。

    (其實不僅限于事件的轉義,包括UI的改變,也需要由系統UI語義轉換到UI業務語義來使用)

     

    UI業務語義事件在Controller控制中的優點是易于理解、維護和擴充,具體的主要有以下方面:

    a.減少系統UI事件判斷邏輯部分代碼的重復。比如在Controller部分代碼無需分步著大量邏輯重復的代碼,當鼠標移動時去判斷究竟是一個2D圖形的尺寸改變,還是一個2D圖形的移動,還是一組2D圖形的移動,還是2D圖形DragAndDrop的動作。

    b.Controller部分的代碼語義明確。在Controller內部處理代碼和接口中直接面對的是UI業務語義,如圖形的移動,圖形的尺寸改變,這樣、代碼易于理解、調試等。

    b.Controller部分代碼無需為系統UI事件保存狀態。如2D圖形的移動中,如果這些事件直接在Controller中處理,從開始MouseDown,MouseMove,到MouseUp過程中,在Controller中要集中保留這樣眾多狀態,極易造成Controller代碼具體多頭職責的癥狀,從而患上嚴重的精神分裂:)

     

    于是乎GEFFrameWork有給出以下的解決方案:

     

    A


     



    如上圖
    A

    GEF通過Tools(interfaceTool),當然在視圖上的MenuToolbar是通過Action發出,這個是eclipseWorkbench機制,在此就不討論了。以下是Tool的類繼承樹:

     

    B



    從上圖
    B可以看出

    Tool繼承的這些類均處理一個或者一類UI業務語義事件,其中需要保留中間狀態的子類均以XXXTracker形式出現。

    首先這些Tool的實現類通過Tool的接口(上圖右邊),接收界面來的事件,然后調用內部handleXXX,這樣通過內部函數getTargetRequest()[createTargetRequest()]和getSourceRequest()[createSourceRequest()],把系統UI事件轉換為UI業務語義事件叫Request(如圖C)。至此Tool會通過調用相關聯的EditPart的接口將UI業務語義事件通知到EditPart中。于是在Controller(EditPart)中僅僅需要理解處理Request對象。

     


     

    C

     

    下面以ResizeTracker代碼為例:

    class ResizeTracker

    protected Request createSourceRequest() {

    ChangeBoundsRequest request;

    request = new ChangeBoundsRequest(REQ_RESIZE);

    request.setResizeDirection(getResizeDirection());

    return request;

    }

    protected Command getCommand() {

    List editparts = getOperationSet();

    EditPart part;

    CompoundCommand command = new CompoundCommand();

    command.setDebugLabel("Resize Handle Tracker");//$NON-NLS-1$

    for (int i = 0; i < editparts.size(); i++) {

    part = (EditPart)editparts.get(i);

    command.add(part.getCommand(getSourceRequest()));

    }

    return command.unwrap();

    }

    protected void eraseTargetFeedback() {

    if (!getFlag(FLAG_TARGET_FEEDBACK))

    return;

    if (getTargetEditPart() != null)

    getTargetEditPart().eraseTargetFeedback(getSourceRequest());

    setFlag(FLAG_TARGET_FEEDBACK, false);

    }

    protected boolean handleButtonUp(int button) {

    if (stateTransition(STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) {

    eraseSourceFeedback();

    eraseTargetFeedback();

    performDrag();

    }

    return true;

    }

     

     

    最后還有個問題是


    Tool
    這些事件接口,如何從Viewer傳遞過來的呢?

     

     

    我畫了一個簡要的類圖


    D


    參照上圖,下面羅列重要代碼:

    大家主要以下兩方面

    一、創建這些關鍵事件處理鏈的過程(注意圖上的粗體文字);

    二、消息從SWTCanvas實例傳遞到Tool過程(圖D中注釋標簽的順序);

     

    class GraphicalEditor

    public void createPartControl(Composite parent) {

    createGraphicalViewer(parent);

    }

    protected void createGraphicalViewer(Composite parent) {

    GraphicalViewer viewer = new ScrollingGraphicalViewer();

    viewer.createControl(parent);

    setGraphicalViewer(viewer);

    configureGraphicalViewer();

    hookGraphicalViewer();

    initializeGraphicalViewer();

    }

    protected void setGraphicalViewer(GraphicalViewer viewer) {

    getEditDomain().addViewer(viewer);

    this.graphicalViewer = viewer;

    }

    class EditDomain

    public void addViewer(EditPartViewer viewer) {

    viewer.setEditDomain(this);

    if (!viewers.contains(viewer))

    viewers.add(viewer);

    }

    class GraphicalViewerImpl

    public void setEditDomain(EditDomain domain) {

    super.setEditDomain(domain);

    // Set the new event dispatcher, even if the new domain is null.  This will dispose

    // the old event dispatcher.

    getLightweightSystem()

    .setEventDispatcher(eventDispatcher = new DomainEventDispatcher(domain, this));

    }

     

    private final LightweightSystem lws = createLightweightSystem();

     

    class ScrollingGraphicalViewer

    public void setEditDomain(EditDomain domain) {

    super.setEditDomain(domain);

    // Set the new event dispatcher, even if the new domain is null.  This will dispose

    // the old event dispatcher.

    getLightweightSystem()

    .setEventDispatcher(eventDispatcher = new DomainEventDispatcher(domain, this));

    }

    class LightweightSystem

    public void setEventDispatcher(EventDispatcher dispatcher) {

    this.dispatcher = dispatcher;  //在此Shapes例子中是DomainEventDispatcher

    dispatcher.setRoot(root);

    dispatcher.setControl(canvas);

    }

    protected void addListeners() {

    EventHandler handler = createEventHandler();

    canvas.getAccessible().addAccessibleListener(handler);

    canvas.getAccessible().addAccessibleControlListener(handler);

    canvas.addMouseListener(handler);

    canvas.addMouseMoveListener(handler);

    canvas.addMouseTrackListener(handler);

    canvas.addKeyListener(handler);

    canvas.addTraverseListener(handler);

    canvas.addFocusListener(handler);

    canvas.addListener(SWT.MouseWheel, handler);

    ……

    setEventDispatcher(getEventDispatcher());

    }

     

    class EventHandler

    implements MouseMoveListener, MouseListener, AccessibleControlListener, KeyListener,

    TraverseListener, FocusListener, AccessibleListener, MouseTrackListener,

    Listener

    {

    public void keyPressed(KeyEvent e) {

     //在此Shapes例子中是DomainEventDispatcher

    getEventDispatcher().dispatchKeyPressed(e);

    }

    public void mouseDoubleClick(MouseEvent e) {

    getEventDispatcher().dispatchMouseDoubleClicked(e);

    }

    public void mouseMove(MouseEvent e) {

    getEventDispatcher().dispatchMouseMoved(e);

    }

    public void mouseUp(MouseEvent e) {

    getEventDispatcher().dispatchMouseReleased(e);

    }

    }

     

    這樣、在圖ARequest發送到EditPart機制做了簡要的探討。

    學習了Tool產生Request的機制,可以幫助我們調試GEF,同時如果在大家自己的程序中需要有新的UI交互類型,也可以試著建立自己的Tool類產生新的Request,這樣在自己的EditPart產生對應的Command,這樣就可以處理實現新的UI交互類型。

     

    在下一篇我們探討一下有關圖A中的EditPart如何產生Command,以及執行Command問題。

    posted on 2005-12-05 13:58 般若菩提 閱讀(2079) 評論(4)  編輯  收藏 所屬分類: GEF源碼分析
    評論:
    • # re: GEF源碼分析(四) GEF 消息轉義 ___ Tool的作用  胡子魚 Posted @ 2005-12-06 17:05
      呵,圖文并茂,寫得很清楚,兄弟辛苦了!

      留言之所以少,可能很多人只是拿來就用,認為在eclipse下配置好就OK,用不著去研究了;另外這里大牛比較多,都在Web framework或者software design……
        回復  更多評論   

    • # re: GEF源碼分析(四) GEF 消息轉義 ___ Tool的作用  鬼谷子 Posted @ 2006-08-15 14:21
      不錯不錯,終于找到一個好地方可以深入學習GEF了~~
      謝謝了哈~~  回復  更多評論   

    • # re: GEF源碼分析(四) GEF 消息轉義 ___ Tool的作用[未登錄]  house Posted @ 2008-01-03 15:54
      好  回復  更多評論   

    • # re: GEF源碼分析(四) GEF 消息轉義 ___ Tool的作用[未登錄]  dragon Posted @ 2009-10-20 15:08
      是不錯,就是你的blog風格有點亂!謝謝!  回復  更多評論   

     
    Copyright © 般若菩提 Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 日本卡1卡2卡三卡免费| 亚洲av午夜福利精品一区| 18观看免费永久视频| 精品亚洲成a人在线观看| 亚洲无成人网77777| 亚洲香蕉成人AV网站在线观看| 免费网站看v片在线香蕉| 91香蕉国产线观看免费全集| a级毛片免费观看在线| 亚洲国产AV无码一区二区三区| 18亚洲男同志videos网站| 亚洲国产另类久久久精品| 亚洲第一视频在线观看免费| 天天摸天天碰成人免费视频| 亚洲免费在线视频播放| 久久免费观看国产99精品| 精品无码国产污污污免费网站国产| 亚洲GV天堂无码男同在线观看| 亚洲一区二区三区四区视频| 日产亚洲一区二区三区| 亚洲AV午夜福利精品一区二区 | 亚洲日本va中文字幕久久| 亚洲国产av一区二区三区| 无码国模国产在线观看免费| 成年美女黄网站18禁免费| 嫖丰满老熟妇AAAA片免费看| 免费看黄视频网站| 性xxxxx免费视频播放| a拍拍男女免费看全片| ww4545四虎永久免费地址| 1000部无遮挡拍拍拍免费视频观看| 久久亚洲免费视频| 免费国产成人午夜在线观看| a级毛片在线免费观看| 免费黄网站在线观看| 免费人成在线观看网站品爱网| 无码一区二区三区免费| 亚在线观看免费视频入口| 99视频在线看观免费| 在免费jizzjizz在线播| 国产1024精品视频专区免费|