<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    精彩的人生

    好好工作,好好生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks
    本文是原創作品,如有轉載,請注明出處!

     

    GEF編輯器的人,不知道有沒有發現這樣一個問題:每當作一個新的編輯器的時候,有很多代碼都和以前的類似。

    我發現了這個問題,很多CommandPolicy,包括EditPart都很類似,所以我經常采用Copy&Paste然后修改的方法來加快開發速度。

    Eclipse采用的是插件擴展機制,做一次擴展就可以向Eclipse貢獻一個新的功能。同理,GEF編輯器中,畫板里的可編輯模型,是否也能這樣添加呢?

    讓我們沿著這個思路走下去。

     

    定義模型

    初步的構想,仍然是繼續前兩篇文章的足跡,更改原來的例子。

     

    模型的定義:
    emfgef3_1.JPG

     

    最開始做這個例子的時候,我將NodeAbstract設置為了true,因為我希望它就是一個抽象類,我將寫RectangleNodeEllipseNode繼承Node,他們才會出現在編輯器里。但是后來發現那樣做的話,文件確實可以編輯,但是文件保存之后,再次用EMF序列化為對象的時候會出錯。

    什么?不信?那你自己試試。

    這里,我給Node加了一個屬性instance,它表示這個對象的實現類。它將給我們代來一些麻煩。

     

    創建模型工程

     

    與前面的文章一樣,利用這個ecore文件創建一個EMF項目,并生成模型代碼。Ok,就把代碼放在這里,不再改動它了。這個工程的名稱是nodenew

     

    創建編輯器工程

     

    如果說前面的工程僅創建了“抽象模型”,那么本工程就僅創建了基于前面模型的一個編輯器框架

    創建一個名為nodenew.gef的插件項目,其他的全部按默認設置。首先,這個插件依賴于nodenew。將nodetest中的commandeditpartconnectionhelppropertiesuicopy過來,將Connection.javaModelManager.javacopy過來,修改代碼,盡可能的減少那些紅叉。

    創建一個擴展點,我們將利用它來初始化編輯器畫板。

    emfgef3_2.JPG


     

    這個擴展點的用意很明確,就是貢獻模型并設置模型與EditPart的對應關系。

     

    創建一個接口類,所有使用這個擴展點的EditPart需要實現這個接口:

    MyEditPart.java

    public interface MyEditPart extends NodeEditPart{
        
    public void setConnection(Object model);
        
    public void removeConnection(Object model);
    }

     

    創建一個類,從擴展點中找到模型與EditPart的對應關系:

     

    ModelToEditPartMap.java

    public class ModelToEditPartMap {
        
        
    private static Hashtable map = getTable();
        
        
    public static Hashtable getTable(){
            
    if(map==null){  
                map
    =new Hashtable();
                IExtensionRegistry registry 
    = Platform.getExtensionRegistry();
                IExtensionPoint point 
    = registry.getExtensionPoint(MyConstants.FACTORY_EXTIONPOINT_ID);
                
    if (null == point){
                    System.err.println(
    "No extension point called "+MyConstants.FACTORY_EXTIONPOINT_ID+" is found!");
                    
    return null;
                }

                IExtension[] extensions 
    = point.getExtensions();
                
    for (int i = 0; i < extensions.length; i++){
                    IConfigurationElement[] elements 
    = extensions[i].getConfigurationElements();
                    
    for (int j = 0; j < elements.length; j++){
                        
    if (elements[j].getAttribute(MyConstants.ATTR_TARGETEDITORID).equals(MyConstants.EDITOR_ID)){
                            String eleType 
    = elements[j].getName();
                            
    if (eleType.equals(MyConstants.ELEMENT_NODEPART)){
                                
    try{
                                    map.put(elements[j].getAttribute(MyConstants.ATTR_MODELCLASS), elements[j]);
                                    System.out.println(
    "add a node " + elements[j].getAttribute(MyConstants.ATTR_NAME) + "to map");
                                }

                                
    catch(Exception e){
                                    e.printStackTrace();
                                }

                            }

                        }

                    }

                }

            }

            
    return map;
        }


    }

     

    創建一個類,從擴展點中得到編輯器畫板里的元素。

     

    FactoryExtension.java

    public class FactoryExtension {    
        
    private static ArrayList factory = getFactory();
        
        
    public static ArrayList getFactory() {
            
    if(factory==null){  
                factory
    =new ArrayList();
                IExtensionRegistry registry 
    = Platform.getExtensionRegistry();
                IExtensionPoint point 
    = registry.getExtensionPoint(MyConstants.FACTORY_EXTIONPOINT_ID);
                
    if (null == point){
                    System.err.println(
    "No extension point called "+MyConstants.FACTORY_EXTIONPOINT_ID+" is found!");
                    
    return null;
                }

                IExtension[] extensions 
    = point.getExtensions();
                
    for (int i = 0; i < extensions.length; i++){
                    IConfigurationElement[] elements 
    = extensions[i].getConfigurationElements();
                    String pluginId 
    = extensions[i].getNamespace();
                    Plugin a 
    = null;
                    
    try {
                        a 
    = extensions[i].getDeclaringPluginDescriptor().getPlugin();
                    }
     catch (InvalidRegistryObjectException e1) {
                        
    // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
     catch (CoreException e1) {
                        
    // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }

                    a.getBundle();
                    
                    
                    
                    
    for (int j = 0; j < elements.length; j++){
                        
    if (elements[j].getAttribute(MyConstants.ATTR_TARGETEDITORID).equals(MyConstants.EDITOR_ID)){
                            String eleType 
    = elements[j].getName();
                            
    if (eleType.equals(MyConstants.ELEMENT_NODEPART)){
                                
    if(!Boolean.parseBoolean(elements[j].getAttribute(MyConstants.ATTR_VISIBLE))){
                                    
    continue;
                                }

                                
    try{
                                    ImageDescriptor descriptor 
    = null;
                                    
    try{
                                        
    if(elements[j].getAttribute(MyConstants.ATTR_ICON)!=null)
                                            descriptor 
    = AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, elements[j].getAttribute(MyConstants.ATTR_ICON));
                                    }
     catch(Exception e){
                                        e.printStackTrace();
                                    }

                                    
    if(descriptor == null){
                                        descriptor 
    = GefPlugin.getImageDescriptor(MyConstants.IMG_DEFAULT);
                                    }

                                    
                                    ToolEntry tool 
    = new CombinedTemplateCreationEntry(
                                            elements[j].getAttribute(MyConstants.ATTR_NAME), 
                                            
    "Create a new Node"
                                            elements[j].getAttribute(MyConstants.ATTR_MODELCLASS), 
                                            
    new MyCreationFactory(elements[j]), descriptor,descriptor);

                                    factory.add(tool);
                                    System.out.println(
    "add a node " + elements[j].getAttribute(MyConstants.ATTR_NAME));
                                }

                                
    catch(Exception e){
                                    e.printStackTrace();
                                }

                            }

                        }

                    }

                }

            }

            
    return factory;
        }

        
        
    }

     

    上面的類中使用的CreationFactory是自己重寫的一個類,它的目的在于,當用戶選中畫板中的一個對象的時候,發出了一個createrequest,我們創建一個對象,封裝在這個request里,當編輯器截獲這個request的時候,就直接得到了新創建的這個模型對象。

     

    MyCreationFactory.java

    public class MyCreationFactory implements CreationFactory{
        
        
    private IConfigurationElement element;
        
        
    public MyCreationFactory(IConfigurationElement element){
            
    this.element = element;
        }

        
        
    public Object getNewObject() 
                    
            
    try {
                Object classname
    =null
                
                
    try {
                    classname 
    = WorkbenchPlugin.createExtension(element, MyConstants.ATTR_MODELCLASS);
                }
     catch (CoreException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                
                
    if(classname instanceof Class)
                    System.out.println(
    "class");
                
                
    return classname;
    //            
            }
     catch (InvalidRegistryObjectException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
            
    return null;
        }

        
    public Object getObjectType() {        
            
    return element.getAttribute(MyConstants.ATTR_MODELCLASS); 
        }


    }

     

    在這里碰到了一個關于ClassLoader的問題。假如不使用WorkbenchPlugin.createExtension(element, MyConstants.ATTR_MODELCLASS);

    從當前的插件項目中load這個class會出現ClassNotFound異常。目前的這個解決方法不是很好,正在尋找更好的解決方案。

     

    接著,修改NodeEditorPaletteFactory,從擴展點中初始化編輯器畫板:

    private static PaletteContainer createShapesDrawer() {
        PaletteDrawer componentsDrawer 
    = new PaletteDrawer("Shapes");
        CombinedTemplateCreationEntry component
    =null;
        ArrayList factory 
    = FactoryExtension.getFactory();
        
    if(factory!=null && factory.size()>1){
            
    for(int i=0; i<factory.size(); i++){
                component 
    = (CombinedTemplateCreationEntry) factory.get(i);
                componentsDrawer.add(component);
            }

        }

        
    return componentsDrawer;
    }

     

    最后,修改NodesEditPartFactory,有些對象需要從擴展點中得到EditPart對象:

    private EditPart getPartForElement(Object modelElement) {
            
    if (modelElement instanceof Diagram) {
                
    return new DiagramEditPart();
            }

            
    if (modelElement instanceof Connection) {
                
    return new ConnectionEditPart();
            }

            
            EditPart result 
    = null;
            
    if(modelElement instanceof Node){
                
                String classname 
    = ((Node)modelElement).getInstance();
                IConfigurationElement element 
    = (IConfigurationElement)ModelToEditPartMap.getTable().get(classname);
                
    try {                
                    result 
    = (EditPart) WorkbenchPlugin.createExtension(element, MyConstants.ATTR_PARTCLASS);
                }
     catch (CoreException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                
            }

            
            
    if(result==null){
            
                
    if(ModelToEditPartMap.getTable().containsKey(modelElement.getClass().getName())){
                    
    try {
                        IConfigurationElement element 
    = (IConfigurationElement)ModelToEditPartMap.getTable().get(modelElement.getClass().getName());
                    
                        result 
    = (EditPart) WorkbenchPlugin.createExtension(element, MyConstants.ATTR_PARTCLASS);

                    }
    catch (CoreException e) {
                        
    // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }

            }

            
            
    if(result!=null && result instanceof MyEditPart){
                ((MyEditPart)result).removeConnection(modelElement);
                ((MyEditPart)result).setConnection(modelElement);            
                
    return result;
            }

            
            
    throw new RuntimeException(
                    
    "Can't create part for model element: "
                    
    + ((modelElement != null? modelElement.getClass().getName() : "null"));
        }

     

    這個時候,編輯器的框架已經搭建好了,運行一下看看吧。
    emfgef3_3.JPG

     

    可以看到,畫板里的Connection是一直都有的,但是卻沒有Node對象。

     

    創建自己的擴展

     

    再建一個新的插件項目,名為nodenew.my,它依賴于前面的2個插件。

     

    首先創建模型對象:

     

    EllipseNode.java

    public class EllipseNode extends NodeImpl{
        
    public EllipseNode(){
            
    super();
            
    this.instance = this.getClass().getName();
        }

    }


    RectangleNode.java

    public class RectangleNode extends NodeImpl{
        
    public RectangleNode(){
            
    super();
            
    this.instance = this.getClass().getName();
        }

    }

     

    接著創建EditPart

     

    EllipseNodeEditPart.java

    public class EllipseNodeEditPart extends NodesEditPart implements MyEditPart{
        
    protected IFigure createFigure() {
            IFigure f 
    = new Ellipse();
            
            f.setOpaque(
    true); // non-transparent figure
            f.setBackgroundColor(ColorConstants.green);
            
    return f;
        }

        
        
    public void removeConnection(Object model){
            
    if(TargetAddConnectionTable.getInstance().contains((Node) model)){
                List l 
    = TargetAddConnectionTable.getInstance().getValue( (Node)model);
                
    if(l!=null && l.size()>0){
                    
    for(int i=0; i<l.size(); i++){
                        Connection c 
    = (Connection) l.get(i);
                        
    this.getModelSourceConnections().add(c);
                        TargetAddConnectionTable.getInstance().remove(c);
                    }

                }

            }

        }
        
        
        
    public void setConnection(Object model){
            
    if(((Node)model).getNext()!=null && ((Node)model).getNext().size()>0){
                
    for(int i=0; i<((Node)model).getNext().size(); i++){
                    Connection c 
    = new Connection();
                    c.setSource((Node) model);
                    c.setTarget((Node) ((Node)model).getNext().get(i));
                    
    this.getModelTargetConnections().add(c);
                    TargetAddConnectionTable.getInstance().add(c, (Node) c.getTarget());
                }

            }

        }


    }

     

    RectangleNodeEditPart.java

    public class RectangleNodeEditPart extends NodesEditPart implements MyEditPart{
        
    protected IFigure createFigure() {
            IFigure f 
    = new RectangleFigure();
            f.setOpaque(
    true); // non-transparent figure
            f.setBackgroundColor(ColorConstants.green);
            
    return f;
        }

        
        
    public void removeConnection(Object model){
            
    if(TargetAddConnectionTable.getInstance().contains((Node) model)){
                List l 
    = TargetAddConnectionTable.getInstance().getValue( (Node)model);
                
    if(l!=null && l.size()>0){
                    
    for(int i=0; i<l.size(); i++){
                        Connection c 
    = (Connection) l.get(i);
                        
    this.getModelSourceConnections().add(c);
                        TargetAddConnectionTable.getInstance().remove(c);
                    }

                }

            }

        }
        
        
        
        
    public void setConnection(Object model){
            
    if(((Node)model).getNext()!=null && ((Node)model).getNext().size()>0){
                
    for(int i=0; i<((Node)model).getNext().size(); i++){
                    Connection c 
    = new Connection();
                    c.setSource((Node) model);
                    c.setTarget((Node) ((Node)model).getNext().get(i));
                    
    this.getModelTargetConnections().add(c);
                    TargetAddConnectionTable.getInstance().add(c, (Node) c.getTarget());
                }

            }

        }


    }

     

    聲明本次擴展:

     

    plugin.xml

    <extension
             
    point="nodenew.gef.editpartfactory">
          
    <nodepart
                
    modelclass="nodenew.model.EllipseNode"
                name
    ="nodenew.my.nodepart1"
                partclass
    ="nodenew.editpart.EllipseNodeEditPart"
                targetEditorId
    ="nodenew.ui.NodesEditor"
                visible
    ="true"/>
          
    <nodepart
                
    modelclass="nodenew.model.RectangleNode"
                name
    ="nodenew.my.nodepart1"
                partclass
    ="nodenew.editpart.RectangleNodeEditPart"
                targetEditorId
    ="nodenew.ui.NodesEditor"
                visible
    ="true"/>
       
    </extension>

     

    看看結果吧
    emfgef3_4.JPG

     

    其他

     

    本例仍然利用兩個action來打開編輯器。

     

    不知道這次的研究成果是不是可以發表成學術論文呢??我覺得挺有創意的,呵呵。

     

    源碼

     

    點擊下載

     

    運行環境

     

    JDK 1.4

    Eclipse 3.1

    EMF

    GEF

    posted on 2005-12-15 15:57 hopeshared 閱讀(3092) 評論(1)  編輯  收藏 所屬分類: EMF&GEF

    Feedback

    # re: emf&gef之三nodenew 2005-12-15 18:00 marmot
    - -!!  回復  更多評論
      

    主站蜘蛛池模板: 国产精品免费一区二区三区| 亚洲黄色网址在线观看| 免费a级黄色毛片| 免费无码看av的网站| 最新中文字幕免费视频| 精品久久久久国产免费| 免费a级毛片高清视频不卡| 久久午夜免费视频| 最近的中文字幕大全免费版| 最近中文字幕无免费视频| 最近中文字幕mv手机免费高清 | 国产免费一区二区三区VR| 毛片a级毛片免费观看免下载| 我们的2018在线观看免费高清| 久视频精品免费观看99| 无码一区二区三区AV免费| 国产免费久久精品99re丫y| 最近中文字幕无吗高清免费视频| 大地资源免费更新在线播放| 青青草国产免费久久久下载| 国产在线观看免费视频播放器| 国产精品美女自在线观看免费| 国产精品色午夜免费视频| 亚洲成a人片在线播放| 国产亚洲精aa成人网站| 国产亚洲精品美女久久久| 亚洲成人福利在线| 亚洲精品123区在线观看| 精品韩国亚洲av无码不卡区 | 亚洲日韩欧洲无码av夜夜摸| 亚洲小视频在线观看| 亚洲国产人成在线观看| 亚洲a∨国产av综合av下载 | 亚洲av不卡一区二区三区| 亚洲六月丁香六月婷婷色伊人| 亚洲中文字幕乱码一区| 人妻仑乱A级毛片免费看| 久久综合给合久久国产免费| 成人A级毛片免费观看AV网站| 国产极品粉嫩泬免费观看| 亚洲一区二区三区无码中文字幕|