隨筆 - 1  文章 - 1  trackbacks - 0
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

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

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

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

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

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

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

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

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

                  setActiveTool(getDefaultTool());
          }


          b、用戶在畫板視圖上按下鼠標(biāo)左鍵后,DomainEventDispatcher會(huì)監(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)建一個(gè)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還會(huì)根據(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中的每一個(gè)模型都實(shí)現(xiàn)了某種Notifier(org.eclipse.emf.common.notify.Notifier)或者IPropertySource(org.eclipse.ui.views.properties.IPropertySource)接口作為消息源,每個(gè)EditPart則相應(yīng)的實(shí)現(xiàn)了Adapter(org.eclipse.emf.common.notify.Adapter)PropertyChangeListener(java.beans.PropertyChangeListener)等接口作為偵聽器。并在EditPart初始化時(shí),將其本身注冊為所對應(yīng)的模型的一個(gè)偵聽器,當(dāng)模型中的屬性發(fā)生變化時(shí),EditPart會(huì)執(zhí)行相應(yīng)的操作。

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

          /**
           * 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ā)生變化時(shí),會(huì)向所有的偵聽器發(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)都會(huì)接收到屬性變化的消息,根據(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自動(dòng)生成,因此使用了Notifier-Adapter偵聽機(jī)制)
          posted @ 2005-11-24 19:57 genesis 閱讀(2355) | 評論 (1)編輯 收藏
          僅列出標(biāo)題  
          主站蜘蛛池模板: 静宁县| 宝兴县| 张掖市| 泰安市| 澎湖县| 德惠市| 莲花县| 饶平县| 鄂托克旗| 舒兰市| 化德县| 天门市| 景德镇市| 剑川县| 龙山县| 当阳市| 孝昌县| 蒙城县| 深州市| 阿克| 英超| 余江县| 伊宁县| 鄱阳县| 行唐县| 兴仁县| 平山县| 韶山市| 华亭县| 女性| 芦溪县| 松滋市| 西吉县| 土默特右旗| 璧山县| 巫溪县| 威远县| 河源市| 宜兰县| 盈江县| 玉溪市|