隨筆 - 1  文章 - 1  trackbacks - 0
          <2005年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          由GEF所構(gòu)建的圖形編輯器用戶通常的操作流程描述如下:

          1、創(chuàng)建需要繪制圖形的文件,并根據(jù)文件類型使用相應的編輯器打開文件,為繪制工作初始化一個圖形編輯視圖。

          2、根據(jù)圖形編輯器所提供的圖元工具創(chuàng)建具體圖元,將圖元繪制于編輯器所提供的圖形編輯視圖之上

          3、已繪制圖形元素的持久化

          根據(jù)這個流程,GEF中的各個類所需要執(zhí)行的操作基本步驟如下:

          1、創(chuàng)建文件,根據(jù)文件類型選擇相應的EditorEditor和相關(guān)的Viewer的初始化(此部分在以后會詳細說明)

          2、使用Editor所提供的PaletteViewer上繪制圖形
          a、用戶選擇想要繪制的圖元,EditDomain會將用戶選擇的Palette中的相應的ToolEntry
          激活。

          private void handlePaletteToolChanged() 
          {
              ToolEntry entry 
          =
           getPaletteViewer().getActiveTool();
              
          if (entry !=null
          )
                  setActiveTool(entry.createTool());
              
          else

                  setActiveTool(getDefaultTool());
          }


          b、用戶在畫板視圖上按下鼠標左鍵后,DomainEventDispatcher會監(jiān)聽鼠標事件

          /**
           * 
          @see EventDispatcher#dispatchMousePressed(org.eclipse.swt.events.MouseEvent)
          */

          public void dispatchMousePressed(org.eclipse.swt.events.MouseEvent me) 
          {
              
          if (!
          editorCaptured) 
          {
                  
          super
          .dispatchMousePressed(me);
                  
          if
           (draw2dBusy())
                      
          return
          ;
              }
              
          if
           (okToDispatch()) 
          {
                  setFocus(
          null
          );
                  control.forceFocus();
                  setRouteEventsToEditor(
          true
          );
                  domain.mouseDown(me, viewer);
              }
          }

          然后根據(jù)事件相應的類型將其路由到EditDomain,EditDomain則根據(jù)事件的類型執(zhí)行相應的操作。這些操作的主要工作就是獲取EditDomain中當前被激活的工具getActiveTool()),然后執(zhí)行該工具對這些鼠標事件的響應。

          public void mouseDown(MouseEvent mouseEvent, EditPartViewer viewer) 
          {
              Tool tool 
          =
           getActiveTool();
              
          if (tool !=null
          )
                  tool.mouseDown(mouseEvent, viewer);
          }

          CreationTool為例,它對ButtonDown事件的響應(handleButtonDown(int))就是創(chuàng)建一個CreateRequest,并賦予其相應的位置信息(setLocation(Point)

          /**
           * The creation tool only works by clicking mouse button 1 (the left mouse button in a
           * right-handed world).  If any other button is pressed, the tool goes into an invalid
           * state.  Otherwise, it goes into the drag state, updates the request's location and 
           * calls {
          @link TargetingTool#lockTargetEditPart(EditPart)} with the edit part that was
           * just clicked on.
           * 
           * 
          @see
           org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)
          */

          protected boolean handleButtonDown(int button) 
          {
              
          if (button !=1

          {
                  setState(STATE_INVALID);
                  handleInvalidInput();
                  
          return true
          ;
              }
              
          if
           (stateTransition(STATE_INITIAL, STATE_DRAG)) 

          {
                  getCreateRequest().setLocation(getLocation());
                  lockTargetEditPart(getTargetEditPart());
                  
          // Snap only when size on drop is employed

                  helper = (SnapToHelper)getTargetEditPart().getAdapter(SnapToHelper.class);
              }
              
          return true
          ;
          }

          c、CreationTool還會根據(jù)Request的類型及位置將其分派給相應的EditPart。[Targeting tools work with a target request. This request is used along with the mouse location to obtain an active target from the current EditPartViewer. This target is then asked for the Command that performs the given request. The target is also asked to show target feedback. (摘自org.eclipse.gef.tools.TargetingTool)]

          d、此后的流程基本上就如GEF EMF Redbook中3.3.3Requests節(jié)中的Communication chain
          Request-EditPart-Command所述


          Command執(zhí)行所做的操作只是對它所涉及到的模型進行相應的設置,譬如大小、位置、顏色等屬性。那么圖元如何顯示在視圖之上呢?這一部分正是由GEF中所使用的MVC模式實現(xiàn)。

          GEF中的每一個模型都實現(xiàn)了某種Notifier(org.eclipse.emf.common.notify.Notifier)或者IPropertySource(org.eclipse.ui.views.properties.IPropertySource)接口作為消息源,每個EditPart則相應的實現(xiàn)了Adapter(org.eclipse.emf.common.notify.Adapter)PropertyChangeListener(java.beans.PropertyChangeListener)等接口作為偵聽器。并在EditPart初始化時,將其本身注冊為所對應的模型的一個偵聽器,當模型中的屬性發(fā)生變化時,EditPart會執(zhí)行相應的操作。

          EditPart
          初始化時,將其本身注冊為所對應的模型的一個偵聽器,并在銷毀之前注銷注冊:

          /**
           * Upon activation, attach to the model element as a notification change
           * listener.
           
          */
          public void activate() {
              
          if (!
          isActive()) {
                  
          super
          .activate();
                  ((ModelElement) getModel()).eAdapters().add(
          this
          );
              }
          }

          /**

           * Upon deactivation, detach from the model element as a notification change
           * listener.
           
          */
          public void deactivate() {
              
          if
           (isActive()) {
                  
          super
          .deactivate();
                  ((ModelElement) getModel()).eAdapters().remove(
          this
          );
              }
          }



          當模型中的屬性發(fā)生變化時,會向所有的偵聽器發(fā)出消息:

          /**
           * <!-- begin-user-doc -->
           * <!-- end-user-doc -->
           * @generated
           
          */
          public void setName(String newName) {
              String oldName 
          =
           name;
              name 
          =
           newName;
              
          if
           (eNotificationRequired())
                  eNotify(
          new ENotificationImpl(this
          , Notification.SET, ModelPackage.ARC_MODEL__NAME, oldName, name));
          }

          對于所有在該模型上注冊的偵聽器(EditPart)都會接收到屬性變化的消息,根據(jù)消息做出相應的反應:
          /*
           * (non-Javadoc)
           * 
           * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
           
          */
          public void notifyChanged(Notification notification) {

              
          int featureID = notification.getFeatureID(ModelPackage.class
          );

              
          if (ModelPackage.NODE_MODEL__HEIGHT ==
           featureID
                      
          || ModelPackage.NODE_MODEL__WIDTH ==
           featureID
                      
          || ModelPackage.NODE_MODEL__X ==
           featureID
                      
          || ModelPackage.NODE_MODEL__Y ==
           featureID) {
                  refreshVisuals();
              } 
          else if (ModelPackage.NODE_MODEL__INPUT_ARCS ==
           featureID) {
                  refreshTargetConnections();
              } 
          else if (ModelPackage.NODE_MODEL__OUTPUT_ARCS ==
           featureID) {
                  refreshSourceConnections();
              }
          }

          (注意:上述示例代碼中,模型部分代碼是由EMF自動生成,因此使用了Notifier-Adapter偵聽機制)
          posted on 2005-11-24 19:57 genesis 閱讀(2354) 評論(1)  編輯  收藏 所屬分類: GEF Related

          FeedBack:
          # re: [Eclipse][GEF]創(chuàng)建圖元的基本流程(一) 2005-11-26 01:58 Dart
          又一個Eclipse Programmer
          歡迎加入我們的社區(qū): www.eclipseworld.org  回復  更多評論
            

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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 巍山| 湄潭县| 营口市| 临潭县| 平乐县| 开封县| 中西区| 甘洛县| 兴海县| 洛阳市| 丰镇市| 蒙山县| 凤山县| 马尔康县| 琼中| 卓资县| 苏州市| 高淳县| 克东县| 雷州市| 潜江市| 夏邑县| 辉县市| 阜南县| 海门市| 克山县| 清水县| 淮阳县| 邢台县| 罗城| 绵阳市| 石台县| 海原县| 长宁县| 盘山县| 梅河口市| 佛山市| 比如县| 三河市| 湛江市| 资兴市|