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

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

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

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

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

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

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

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

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

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

                  setActiveTool(getDefaultTool());
          }


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

          /**
           * 
          @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ù)事件相應(yīng)的類型將其路由到EditDomainEditDomain則根據(jù)事件的類型執(zhí)行相應(yīng)的操作。這些操作的主要工作就是獲取EditDomain中當(dāng)前被激活的工具getActiveTool()),然后執(zhí)行該工具對這些鼠標(biāo)事件的響應(yīng)。

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

          CreationTool為例,它對ButtonDown事件的響應(yīng)(handleButtonDown(int))就是創(chuàng)建一個CreateRequest,并賦予其相應(yīng)的位置信息(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
          ;
          }

          cCreationTool還會根據(jù)Request的類型及位置將其分派給相應(yīng)的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í)行所做的操作只是對它所涉及到的模型進(jìn)行相應(yīng)的設(shè)置,譬如大小、位置、顏色等屬性。那么圖元如何顯示在視圖之上呢?這一部分正是由GEF中所使用的MVC模式實(shí)現(xiàn)。

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

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

          /**
           * 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
          );
              }
          }



          當(dāng)模型中的屬性發(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ù)消息做出相應(yīng)的反應(yīng):
          /*
           * (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偵聽機(jī)制)
          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ù)  更多評論
            

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 保德县| 石棉县| 威信县| 临颍县| 尖扎县| 麻阳| 石景山区| 江永县| 邳州市| 鄂温| 临高县| 太仆寺旗| 乡城县| 岢岚县| 巴中市| 明星| 丹东市| 缙云县| 任丘市| 静安区| 武平县| 吉木乃县| 横山县| 精河县| 遵化市| 体育| 若羌县| 辛集市| 黑水县| 黑龙江省| 邯郸县| 乃东县| 沈阳市| 白水县| 肇庆市| 福贡县| 康平县| 怀集县| 宽甸| 五常市| 岢岚县|