posts - 36, comments - 30, trackbacks - 0, articles - 3
          要實(shí)現(xiàn)向編輯器增加活動(dòng),我們應(yīng)該在面板上選一種活動(dòng)(開(kāi)始活動(dòng),普通活動(dòng),結(jié)束活動(dòng)),拖到編輯器中。為此我們必須在面板和編輯器中分別加監(jiān)聽(tīng)。修改WorkflowProcessEditor類(lèi)
          在編輯器的GraphicalViewer加監(jiān)聽(tīng)

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

              }
          ;
          }

          同時(shí)我們還必須給面板加監(jiān)聽(tīng),覆蓋父類(lèi)的createPaletteViewerProvider()方法:

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

                 }
          ;
          }

          光在這兩個(gè)地方加監(jiān)聽(tīng),還不夠,這里還要引出gef的重要概念:策略(Policy),用過(guò)Rose的人都知道,我們可以新建一個(gè)類(lèi)圖,移動(dòng)它,刪除它,這在流程設(shè)計(jì)器中也可以,只是新建活動(dòng),移動(dòng)活動(dòng)等操作,用戶(hù)這些操作其實(shí)是對(duì)控制器的操作,比如用戶(hù)用鼠標(biāo)移動(dòng)活動(dòng),其實(shí)這過(guò)程包括用戶(hù)向控制器發(fā)出移動(dòng)活動(dòng)的請(qǐng)求(Request),控制器就調(diào)用相應(yīng)的命令(Command)來(lái)修改模型中活動(dòng)的位置屬性,而模型的位置屬性發(fā)生變化,又會(huì)通知控制器,控制器就會(huì)刷新視圖,改變活動(dòng)的位置,這樣,我們就移動(dòng)了活動(dòng),那么控制器是怎么根據(jù)請(qǐng)求的類(lèi)型調(diào)用相應(yīng)的命令的,這就是策略的作用,簡(jiǎn)單說(shuō),策略保存了請(qǐng)求類(lèi)型和命令的映射關(guān)系,它知道什么樣的請(qǐng)求要調(diào)用哪個(gè)命令。

          明白策略的含義之后,就可以更好的理解我們下面的程序了。我們要向流程中增加一個(gè)活動(dòng),就要向流程控制器發(fā)出請(qǐng)求,因此,我們要在流程控制器中安裝策略,由于我們?cè)诰庉嬈髦胁捎媒^對(duì)定位方式,因此安裝XYLayoutEditPolicy策略,我們定義一個(gè)類(lèi)WorkflowProcessXYLayoutEditPolicy繼承它,

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

          其實(shí)這個(gè)策略不僅可以處理創(chuàng)建活動(dòng)的請(qǐng)求,還可以處理改變活動(dòng)位置和大小的請(qǐng)求。
          接下來(lái)我們來(lái)看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;
              }

           
          }

          如果我們發(fā)出在編輯器中新建活動(dòng)的請(qǐng)求,流程根據(jù)安裝的策略,就會(huì)調(diào)用這個(gè)類(lèi)的getCreateCommand方法,為此我們要修改這個(gè)方法,如果我們發(fā)出改變活動(dòng)大小和位置的請(qǐng)求,就會(huì)調(diào)用createChangeConstraintCommand方法。
          為了修改流程模型,在流程模型中增加一個(gè)活動(dòng),我們用命令來(lái)實(shí)現(xiàn)這個(gè)功能,命令都具有撤銷(xiāo),重做功能,我們只需覆蓋redo,undo方法就可以實(shí)現(xiàn)這功能。:

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

           
              
          /* 撤銷(xiāo)
               
          */

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

          }


          接下來(lái),我們還要修改WorkflowProcessXYLayoutEditPolicy的getCreateCommand方法,如果在編輯器中請(qǐng)求創(chuàng)建的對(duì)象是開(kāi)始活動(dòng),活動(dòng),結(jié)束活動(dòng)的一種,都會(huì)調(diào)用剛才新建的命令。

          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;
          }

           

          這下,我運(yùn)行這個(gè)項(xiàng)目,我們從面板選中一個(gè)活動(dòng),放在編輯器中,編輯器根本沒(méi)有反映,其實(shí)是我們少寫(xiě)了一個(gè)地方,我們向編輯器放一個(gè)活動(dòng),向流程控制器發(fā)出在編輯器中增加活動(dòng)的請(qǐng)求,流程編輯器根據(jù)安裝的策略,調(diào)用相應(yīng)的命令修改流程模型,在流程模型中增加活動(dòng)模型,而此時(shí)流程模型發(fā)生了變化,控制器應(yīng)該刷新流程模型對(duì)應(yīng)的視圖,而我們程序是沒(méi)有寫(xiě)這段代碼的,因此我們要修改WorkflowProcessEditPart的propertyChange方法,由于在WorkflowProcess模型中,當(dāng)向模型中增加活動(dòng)時(shí)通知控制器流程的CHILD_ADDED_PROP發(fā)生變化的,見(jiàn)如下代碼:

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

                 
          return false;
          }

          為此我們?cè)趐ropertyChange應(yīng)作如下修改:

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

          }

          以上程序的意思是,當(dāng)往流程模型中增加活動(dòng)或者從流程模型中刪除活動(dòng)時(shí),刷新流程模型包含子元素對(duì)應(yīng)的視圖,而流程模型的子元素是活動(dòng)模型,而活動(dòng)模型控制器的refreshVisuals()我們也沒(méi)有實(shí)現(xiàn),因此我們也應(yīng)該實(shí)現(xiàn)這個(gè)方法,定義如下:

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

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

          這個(gè)方法的含義是取得活動(dòng)模型的位置,大小信息,把當(dāng)前活動(dòng)模型定位到編輯器的適當(dāng)位置。
          這下,我們?cè)龠\(yùn)行項(xiàng)目,就可以順利把活動(dòng)添加到編輯器中了。

          在下一節(jié),我們將介紹如何移動(dòng),刪除活動(dòng),改變活動(dòng)的大小,在活動(dòng)之間新建轉(zhuǎn)移

          主站蜘蛛池模板: 佛冈县| 随州市| 康乐县| 固阳县| 皮山县| 延吉市| 郴州市| 通城县| 阳江市| 富民县| 蒲江县| 彭阳县| 攀枝花市| 永城市| 晋城| 镇原县| 年辖:市辖区| 古蔺县| 镇江市| 西畴县| 晋州市| 崇信县| 灌南县| 普宁市| 汉中市| 闵行区| 沈丘县| 聂荣县| 甘谷县| 澳门| 连州市| 双辽市| 噶尔县| 乃东县| 综艺| 宕昌县| 亚东县| 陆河县| 绥化市| 萨迦县| 于都县|