posts - 36, comments - 30, trackbacks - 0, articles - 3

          流程設計器開發四(策略和命令部分)

          Posted on 2008-01-04 08:49 笑看人生 閱讀(1405) 評論(0)  編輯  收藏 所屬分類: Java插件開發
          要實現向編輯器增加活動,我們應該在面板上選一種活動(開始活動,普通活動,結束活動),拖到編輯器中。為此我們必須在面板和編輯器中分別加監聽。修改WorkflowProcessEditor類
          在編輯器的GraphicalViewer加監聽

          protectedvoid initializeGraphicalViewer() {
              
          super.initializeGraphicalViewer();
              GraphicalViewer viewer 
          = getGraphicalViewer();
              viewer.setContents(getModel()); 
          // set the contents of this editor
              
              
          // listen for dropped parts
              viewer.addDropTargetListener(createTransferDropTargetListener());
          }

           
          private TransferDropTargetListener createTransferDropTargetListener() {
              returnnew TemplateTransferDropTargetListener(getGraphicalViewer()) 
          {
                 
          protected CreationFactory getFactory(Object template) {
                     returnnew SimpleFactory((Class) template);
                 }

              }
          ;
          }

          同時我們還必須給面板加監聽,覆蓋父類的createPaletteViewerProvider()方法:

          protected PaletteViewerProvider createPaletteViewerProvider() {
                 returnnew PaletteViewerProvider(getEditDomain()) 
          {
                     protectedvoid configurePaletteViewer(PaletteViewer viewer) 
          {
                        
          super.configurePaletteViewer(viewer);            
                     viewer.addDragSourceListener(
          new TemplateTransferDragSourceListener(viewer));
                     }

                 }
          ;
          }

          光在這兩個地方加監聽,還不夠,這里還要引出gef的重要概念:策略(Policy),用過Rose的人都知道,我們可以新建一個類圖,移動它,刪除它,這在流程設計器中也可以,只是新建活動,移動活動等操作,用戶這些操作其實是對控制器的操作,比如用戶用鼠標移動活動,其實這過程包括用戶向控制器發出移動活動的請求(Request),控制器就調用相應的命令(Command)來修改模型中活動的位置屬性,而模型的位置屬性發生變化,又會通知控制器,控制器就會刷新視圖,改變活動的位置,這樣,我們就移動了活動,那么控制器是怎么根據請求的類型調用相應的命令的,這就是策略的作用,簡單說,策略保存了請求類型和命令的映射關系,它知道什么樣的請求要調用哪個命令。

          明白策略的含義之后,就可以更好的理解我們下面的程序了。我們要向流程中增加一個活動,就要向流程控制器發出請求,因此,我們要在流程控制器中安裝策略,由于我們在編輯器中采用絕對定位方式,因此安裝XYLayoutEditPolicy策略,我們定義一個類WorkflowProcessXYLayoutEditPolicy繼承它,

          我們修改WorkflowProcessEditPart類的createEditPolicies方法:
          protectedvoid createEditPolicies() 
                 installEditPolicy(EditPolicy.LAYOUT_ROLE, 
          new WorkflowProcessXYLayoutEditPolicy());
                 
          }

          其實這個策略不僅可以處理創建活動的請求,還可以處理改變活動位置和大小的請求。
          接下來我們來看WorkflowProcessXYLayoutEditPolicy


          package com.example.workflow.policy;
           
          import org.eclipse.gef.EditPart;
          import org.eclipse.gef.commands.Command;
          import org.eclipse.gef.editpolicies.XYLayoutEditPolicy;
          import org.eclipse.gef.requests.CreateRequest;
           
          publicclass WorkflowProcessXYLayoutEditPolicy 
          extends XYLayoutEditPolicy{
           
              
          protected Command createChangeConstraintCommand(EditPart arg0, Object arg1) {
                 
          // TODO Auto-generated method stub
                 returnnull;
              }

           
              
          protected Command getCreateCommand(CreateRequest arg0) {
                 
          // TODO Auto-generated method stub
                 returnnull;
              }

           
          }

          如果我們發出在編輯器中新建活動的請求,流程根據安裝的策略,就會調用這個類的getCreateCommand方法,為此我們要修改這個方法,如果我們發出改變活動大小和位置的請求,就會調用createChangeConstraintCommand方法。
          為了修改流程模型,在流程模型中增加一個活動,我們用命令來實現這個功能,命令都具有撤銷,重做功能,我們只需覆蓋redo,undo方法就可以實現這功能。:

          package com.example.workflow.commands;
           
          import org.eclipse.draw2d.geometry.Dimension;
          import org.eclipse.draw2d.geometry.Rectangle;
          import org.eclipse.gef.commands.Command;
           
          import com.example.workflow.model.AbstractActivity;
          import com.example.workflow.model.WorkflowProcess;
           
           
           
          publicclass AbstractActivityCreateCommand 
          extends Command{
              
              
          private AbstractActivity newActivity;
              
              privatefinal WorkflowProcess parent;
              
              
          private Rectangle bounds;
           
              
          public AbstractActivityCreateCommand(AbstractActivity newActivity, WorkflowProcess parent, Rectangle bounds) {
                 
          this.newActivity = newActivity;
                 
          this.parent = parent;
                 
          this.bounds = bounds;
                 setLabel(
          "activity creation");
              }

           
              
              publicboolean canExecute() 
          {
                 returnnewActivity 
          != null && parent != null && bounds != null;
              }

           
              
          /* (non-Javadoc)
               * @see org.eclipse.gef.commands.Command#execute()
               
          */

              publicvoid execute() 
          {
                 newActivity.setLocation(bounds.getLocation());
                 Dimension size 
          = bounds.getSize();
                 
          if (size.width > 0 && size.height > 0)
                     newActivity.setSize(size);
                 redo();
              }

           
              
          /* 重做
               
          */

              publicvoid redo() 
          {
                 parent.addChild(newActivity);
              }

           
              
          /* 撤銷
               
          */

              publicvoid undo() 
          {
                 parent.removeChild(newActivity);
              }

          }


          接下來,我們還要修改WorkflowProcessXYLayoutEditPolicy的getCreateCommand方法,如果在編輯器中請求創建的對象是開始活動,活動,結束活動的一種,都會調用剛才新建的命令。

          protected Command getCreateCommand(CreateRequest request) {
                 Object childClass 
          = request.getNewObjectType();
                 
          if (childClass == StartActivity.class
                        
          ||childClass == Activity.class
                        
          ||childClass == EndActivity.class{          
                     returnnew AbstractActivityCreateCommand((AbstractActivity)request.getNewObject(), 
                            (WorkflowProcess)getHost().getModel(), (Rectangle)getConstraintFor(request));
                 }

                 
          return null;
          }

           

          這下,我運行這個項目,我們從面板選中一個活動,放在編輯器中,編輯器根本沒有反映,其實是我們少寫了一個地方,我們向編輯器放一個活動,向流程控制器發出在編輯器中增加活動的請求,流程編輯器根據安裝的策略,調用相應的命令修改流程模型,在流程模型中增加活動模型,而此時流程模型發生了變化,控制器應該刷新流程模型對應的視圖,而我們程序是沒有寫這段代碼的,因此我們要修改WorkflowProcessEditPart的propertyChange方法,由于在WorkflowProcess模型中,當向模型中增加活動時通知控制器流程的CHILD_ADDED_PROP發生變化的,見如下代碼:

          public boolean addChild(AbstractActivity a) {
                 
          if (a != null && activities.add(a)) {
                     firePropertyChange(CHILD_ADDED_PROP, 
          null, a);
                     
          return true;
                 }

                 
          return false;
          }

          為此我們在propertyChange應作如下修改:

          public void propertyChange(PropertyChangeEvent evt) {
                 String prop 
          = evt.getPropertyName();
                 
          if (WorkflowProcess.CHILD_ADDED_PROP.equals(prop)
                        
          || WorkflowProcess.CHILD_REMOVED_PROP.equals(prop)) {
                     refreshChildren();
                  }

          }

          以上程序的意思是,當往流程模型中增加活動或者從流程模型中刪除活動時,刷新流程模型包含子元素對應的視圖,而流程模型的子元素是活動模型,而活動模型控制器的refreshVisuals()我們也沒有實現,因此我們也應該實現這個方法,定義如下:

          private AbstractActivity getCastedModel() {
                 
          return (AbstractActivity) getModel();
              }

              
              protectedvoid refreshVisuals() 
          {      
                 Rectangle bounds 
          = new Rectangle(getCastedModel().getLocation(),
                        getCastedModel().getSize());
                 ((GraphicalEditPart) getParent()).setLayoutConstraint(
          this, getFigure(), bounds);
          }

          這個方法的含義是取得活動模型的位置,大小信息,把當前活動模型定位到編輯器的適當位置。
          這下,我們再運行項目,就可以順利把活動添加到編輯器中了。

          在下一節,我們將介紹如何移動,刪除活動,改變活動的大小,在活動之間新建轉移

          主站蜘蛛池模板: 岫岩| 新河县| 清涧县| 同心县| 铁岭县| 呼图壁县| 溆浦县| 漳平市| 安泽县| 海林市| 佳木斯市| 宜城市| 兴和县| 东台市| 永嘉县| 织金县| 南城县| 宁海县| 大关县| 无锡市| 华蓥市| 阿巴嘎旗| 武定县| 西贡区| 祁阳县| 莎车县| 二连浩特市| 紫云| 海城市| 台东市| 芮城县| 潍坊市| 阳江市| 错那县| 理塘县| 巧家县| 绍兴市| 东阳市| 搜索| 广州市| 凤台县|