精彩的人生

          好好工作,好好生活

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks

          常用鏈接

          留言簿(43)

          隨筆分類

          隨筆檔案

          相冊(cè)

          收藏夾

          Friends

          Web Site

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          八進(jìn)制寫的關(guān)于GEF以及EMF的文章,對(duì)我當(dāng)時(shí)的工作幫助很大。

           

          我最初看的是他的關(guān)于GEF的文章,但是我的工作需要將GEFEMF結(jié)合,本文使用的例子就是根據(jù)八進(jìn)制的Bloggefpractice改編而成。

           

           

          定義模型

           

          自從EMF出現(xiàn)以后,出現(xiàn)了一種新的說法:模型驅(qū)動(dòng)的軟件開發(fā)(例如Marlin),經(jīng)過這段時(shí)間的研究開發(fā),發(fā)現(xiàn)使用GEFEMF確實(shí)是這樣,一旦模型定義好了,這個(gè)項(xiàng)目就基本定型了。

           

          Ok,廢話留著以后慢慢說,進(jìn)入正題先。

           

          首先,定義模型。在gefpractice這個(gè)例子中,模型很簡(jiǎn)單,只有三類元素:DiagramNodeConnection。他們之間的關(guān)系,用EMF的模型文件(ecore)定義出來就是這樣的:

          1.JPG

          在做模型定義的時(shí)候,需要注意他們之間的包含關(guān)系。打開Properties視圖,有一個(gè)
          2.JPG

          Containment屬性需要格外注意,因?yàn)樗鼘Q定該接點(diǎn)是一個(gè)屬性還是一個(gè)子節(jié)點(diǎn)。以上圖為例,這個(gè)屬性設(shè)置為true,那么xml文件的格式是

          <Diagram>

          <Node/>

          </Diagram>

           

          假如是false,那么就是

          <Diagram nodes=”//node.0”/>

          <Node />

           

          由于有這個(gè)問題,在定義Node的時(shí)候就一定要注意sourceConnectionstargetConnections的這個(gè)屬性,一個(gè)是true,另一個(gè)是false。(自己想想,為什么呢?^-^

           

          當(dāng)然模型的定義并不是只有這種方式,只要你將邏輯表述對(duì)了,這個(gè)模型就沒有問題。

           

          創(chuàng)建工程

           

          用這個(gè)模型創(chuàng)建一個(gè)EMF Project。操作過程是New -> Project -> EMF Project -> 工程名稱是eclipse.my.gefpractice -> 選擇Ecore Model -> 選擇定義好的nodeemf.ecoreload -> 其他的按照默認(rèn)選擇。這樣,你的工作區(qū)就創(chuàng)建了這個(gè)工程。

          這個(gè)新建的工程有個(gè)model文件夾,里面有nodeemf.ecorenodeemf.genmodel兩個(gè)文件。用當(dāng)前默認(rèn)的編輯器打開nodeemf.genmodel文件,更改根節(jié)點(diǎn)(Nodeemf)的子節(jié)點(diǎn)(nodeemf)的屬性(從屬性視圖中改)
          3.JPG

          接著,右鍵選擇上圖中的根節(jié)點(diǎn),選擇Generate Model Code。這樣,模型的代碼就全部生成了。

           

          事件監(jiān)聽

           

          一般,完全使用GEF的情況下,模型的監(jiān)聽是通過模型實(shí)現(xiàn)PropertySource來實(shí)現(xiàn)的。詳細(xì)的請(qǐng)參看八進(jìn)制的相關(guān)文章。但是本文中使用EMF來定義模型,那么原則上就不修改生成的代碼。那么,這里利用Adapter來給模型“安裝”屬性。

           

          這里給出一段示例代碼

          public class NodePropertySource extends AbstractPropertySource {
              
              
          private static final String ID_X = "X";
              
          private static final String ID_Y = "Y";
              
          private static final String ID_NAME = "Name";
              
          private static final String ID_VISIBLE = "Visible";
              
              
          public NodePropertySource(Object model) {
                  
          super(model);
              }

              
              
          private Node getNode() {
                  
          return (Node) getModel();
              }

              
              
          public void createPropertyDescriptors(List descriptors) {
                  descriptors.add(
          new TextPropertyDescriptor(ID_X, ID_X));
                  descriptors.add(
          new TextPropertyDescriptor(ID_Y, ID_Y));
                  descriptors.add(
          new TextPropertyDescriptor(ID_NAME, ID_NAME));
                  descriptors.add(
          new TextPropertyDescriptor(ID_VISIBLE, ID_VISIBLE));
              }

              
              
          public Object getPropertyValue(Object id) {
                  
          if(id == ID_X) {
                      
          return Integer.toString(getNode().getX());
                  }

                  
          if(id == ID_Y) {
                      
          return Integer.toString(getNode().getY());
                  }

                  
          if(id == ID_NAME) {
                      
          return getNode().getName();
                  }

                  
          if(id == ID_VISIBLE) {
                      
          return Boolean.toString(getNode().isVisible());
                  }

                  
          return null;
              }

              
              
          public void setPropertyValue(Object id, Object value) {
                  
          if (id == ID_X) {
                      getNode().setX(Integer.parseInt(value.toString()));
                  }
           else if (id == ID_Y) {
                      getNode().setY(Integer.parseInt(value.toString()));
                  }
           else if (id == ID_NAME) {
                      getNode().setName(value.toString());
                  }
           else if(id == ID_VISIBLE) {
                      getNode().setVisible(Boolean.getBoolean(value.toString()));
                  }

              }

              
          }


          在這個(gè)模型對(duì)應(yīng)的EditPart中安裝這個(gè)PropertySource
          public Object getAdapter(Class key) {
                  
          if (IPropertySource.class == key)
                      
          return new NodePropertySource(getModel());
                  
          return super.getAdapter(key);
              }


          由于用
          EMF定義的model本身就實(shí)現(xiàn)了notifier,故在本例中采用了EMF的事件監(jiān)聽機(jī)制。(采用GEF的事件監(jiān)聽機(jī)制也是可行的)
          public void notifyChanged(Notification notification) {
                  
          int type = notification.getEventType();
                  
          int featureId = notification.getFeatureID(ModelPackage.class);
                  
          switch(type) {
                  
          case Notification.SET:
                      
          switch(featureId) {
                      
          case ModelPackage.NODE__X:
                      
          case ModelPackage.NODE__Y:
                      
          case ModelPackage.NODE__NAME:
                      
          case ModelPackage.NODE__VISIBLE:
                          refreshVisuals();
                          
          break;
                      }

                  
          case Notification.ADD:
                  
          case Notification.REMOVE:
                      
          switch(featureId) {
                      
          case ModelPackage.NODE__INPUTS:
                          refreshSourceConnections();
                          
          break;
                      
          case ModelPackage.NODE__OUTPUTS:
                          refreshTargetConnections();
                          
          break;
                      }

                  }

              }


          編輯器

           

          編輯器的其他重要組成部分,如Commandpolicy根原來的基本上沒區(qū)別,這里就不再敘述了。

           

          其他

           

          本例中不能從左邊的Explorer視圖中打開這個(gè)編輯器,而是用了Open ActionNew Action。原因是本插件項(xiàng)目打包后可以加載到Rcp項(xiàng)目中。

           

          本例的運(yùn)行結(jié)果
          4.JPG

          除了上圖中的問題外,還有一些小bug,呵呵,我比較懶,基本不用它,所以就沒有改(Eclipse的懶加載法則)。這是我的一個(gè)面試考題,做這個(gè)例子,共用了1.5天。

           

           

          源碼

           

          點(diǎn)擊下載

           

          環(huán)境

           

          JDK1.4

          Eclipse 3.1

          GEF

          EMF

          posted on 2005-11-27 12:43 hopeshared 閱讀(2415) 評(píng)論(7)  編輯  收藏 所屬分類: EMF&GEF

          Feedback

          # re: emf&gef之一example.my.gefpractice 2005-11-29 17:20 wangzhiwei
          你是北航軟院哪一級(jí)的?  回復(fù)  更多評(píng)論
            

          # re: emf&gef之一example.my.gefpractice 2005-12-31 22:55 pandawang
          http://www.eclipseworld.org/bbs/read.php?tid=785&fpage=1
          剛剛看倒這個(gè)  回復(fù)  更多評(píng)論
            

          # re: emf&gef之一example.my.gefpractice 2006-01-02 12:21 hopeshared
          那個(gè)也是我發(fā)的  回復(fù)  更多評(píng)論
            

          # re: emf&gef之一example.my.gefpractice 2007-01-05 16:25 alf
          are you ?  回復(fù)  更多評(píng)論
            

          # re: emf&gef之一example.my.gefpractice 2007-01-05 16:29 alf
          hehe!
          時(shí)隔一年啊.....
          才看到......
          感謝
          你在那個(gè)公司啊?
          Boss 給你開多少啊....
          只是問問//看看是否有前途啊...Eclipse
            回復(fù)  更多評(píng)論
            

          # re: emf&gef之一example.my.gefpractice 2007-05-15 09:56 jack.yuan
          由于有這個(gè)問題,在定義Node的時(shí)候就一定要注意sourceConnections和targetConnections的這個(gè)屬性,一個(gè)是true,另一個(gè)是false。

          我沒有想明白,請(qǐng)明示,謝謝!  回復(fù)  更多評(píng)論
            

          # re: emf&gef之一example.my.gefpractice 2013-06-19 17:39 瘋狂De年糕
          @jack.yuan
          雖然已經(jīng)過去N年了,但是還是希望能給后來可能看到的人以回答。也許不理解之前看到博主的這句話的確會(huì)有些困惑
          containment這個(gè)屬性表示了兩個(gè)EClass的強(qiáng)關(guān)聯(lián)關(guān)系
          sourceConnections和targetConnections如果將這個(gè)屬性同時(shí)設(shè)置為true,那么很遺憾,由于emf的驗(yàn)證機(jī)制,一個(gè)Connection對(duì)象只能存在在這兩個(gè)集合之一
          如果同時(shí)設(shè)置為false,那么在寫入xml作持久化時(shí)會(huì)報(bào)錯(cuò),因?yàn)閏onnection對(duì)象無法被識(shí)別為任何一個(gè)對(duì)象的子節(jié)點(diǎn)被保存
          解決方法之一即一個(gè)設(shè)為true,一個(gè)設(shè)為false。另一種方式參考八進(jìn)制的方式,兩個(gè)都設(shè)置為false,但是需要多一個(gè)connections集合,diagram除與nodes結(jié)合關(guān)聯(lián)外還與這個(gè)connections集合關(guān)聯(lián),當(dāng)然這里的containment屬性為true  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 深州市| 云安县| 安宁市| 邳州市| 营山县| 承德市| 墨玉县| 洪洞县| 红桥区| 金堂县| 阿勒泰市| 长葛市| 五寨县| 宁德市| 年辖:市辖区| 枞阳县| 惠东县| 佛山市| 黄冈市| 咸宁市| 金溪县| 莲花县| 邯郸县| 新疆| 正蓝旗| 彩票| 武定县| 甘肃省| 镇雄县| 巨野县| 扶余县| 资阳市| 尚志市| 新津县| 彩票| 宁陵县| 康乐县| 侯马市| 大石桥市| 重庆市| 柞水县|