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

          導(dǎo)航

          常用鏈接

          留言簿(11)

          我參與的團(tuán)隊

          隨筆分類

          隨筆檔案

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 31806
          • 排名 - 1336

          最新評論

          閱讀排行榜

          評論排行榜

           

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

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


          接著上一節(jié):

          我們先解決如下問題:

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

           

           

          術(shù)語定義:

          系統(tǒng)UI事件:        一般由某些計算機(jī)人機(jī)交互硬件發(fā)出信號,并且經(jīng)操作系統(tǒng)理解后產(chǎn)生的事件,例如:原始的鼠標(biāo)的移動、點(diǎn)擊和鍵盤的敲擊事件等。

          UI業(yè)務(wù)語義事件: 由系統(tǒng)UI事件和其它UI業(yè)務(wù)語義事件觸發(fā),由UI業(yè)務(wù)代碼理解后產(chǎn)生的事件(操作系統(tǒng)不可理解,同時無任何領(lǐng)域的業(yè)務(wù)語義),如2D圖形的尺寸調(diào)整,2D圖形的點(diǎn)擊,2D圖形的移動。

          (其實不僅限于事件的轉(zhuǎn)義,包括UI的改變,也需要由系統(tǒng)UI語義轉(zhuǎn)換到UI業(yè)務(wù)語義來使用)

           

          UI業(yè)務(wù)語義事件在Controller控制中的優(yōu)點(diǎn)是易于理解、維護(hù)和擴(kuò)充,具體的主要有以下方面:

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

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

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

           

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

           

          A


           



          如上圖
          A

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

           

          B



          從上圖
          B可以看出

          Tool繼承的這些類均處理一個或者一類UI業(yè)務(wù)語義事件,其中需要保留中間狀態(tài)的子類均以XXXTracker形式出現(xiàn)。

          首先這些Tool的實現(xiàn)類通過Tool的接口(上圖右邊),接收界面來的事件,然后調(diào)用內(nèi)部handleXXX,這樣通過內(nèi)部函數(shù)getTargetRequest()[createTargetRequest()]和getSourceRequest()[createSourceRequest()],把系統(tǒng)UI事件轉(zhuǎn)換為UI業(yè)務(wù)語義事件叫Request(如圖C)。至此Tool會通過調(diào)用相關(guān)聯(lián)的EditPart的接口將UI業(yè)務(wù)語義事件通知到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


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

          大家主要以下兩方面

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

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

           

          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發(fā)送到EditPart機(jī)制做了簡要的探討。

          學(xué)習(xí)了Tool產(chǎn)生Request的機(jī)制,可以幫助我們調(diào)試GEF,同時如果在大家自己的程序中需要有新的UI交互類型,也可以試著建立自己的Tool類產(chǎn)生新的Request,這樣在自己的EditPart產(chǎn)生對應(yīng)的Command,這樣就可以處理實現(xiàn)新的UI交互類型。

           

          在下一篇我們探討一下有關(guān)圖A中的EditPart如何產(chǎn)生Command,以及執(zhí)行Command問題。

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

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

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

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

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

           
          Copyright © 般若菩提 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 荔波县| 仙桃市| 日喀则市| 布尔津县| 苍溪县| 大姚县| 广元市| 新宁县| 家居| 石河子市| 雅安市| 义马市| 泌阳县| 高碑店市| 肥城市| 涿鹿县| 西华县| 桦南县| 小金县| 萝北县| 江油市| 江都市| 白水县| 东乌珠穆沁旗| 赤城县| 永川市| 新疆| 云安县| 朝阳区| 乐昌市| 韩城市| 深水埗区| 鹿泉市| 江都市| 西华县| 嵊州市| 肇东市| 曲水县| 江油市| 扶余县| 宜君县|