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

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

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

    sharky的點滴積累

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      56 隨筆 :: 104 文章 :: 10 評論 :: 0 Trackbacks

    兩天前GEF發布了3.1M7版本,但使用下來發現和M6沒有什么區別,是不是主要為了和Eclipse版本相配套?希望3.1正式版早日發布,應該會新增不少內容。上一篇帖子介紹了如何實現表格功能,在開發過程中,另一個經常用到的功能就是樹,雖然SWT提供了標準的樹控件,但使用它完成如組織結構圖這樣的應用還是不夠直觀和方便。在目前版本(3.1M7)的GEF中雖然沒有直接支持樹的實現,但Draw2D提供的例子程序里卻有我們可以利用的代碼(org.eclipse.draw2d.examples.tree.TreeExample,運行界面見下圖),通過它可以節約不少工作量。

    treeexample.gif
    圖1 Draw2D例子中的TreeExample

    記得數年前曾用Swing做過一個組織結構圖的編輯工具,當時的實現方式是讓畫布使用XYLayout,在適當的時候計算和刷新每個樹節點的位置,算法的思想則是深度優先搜索,非樹葉節點的位置由其子節點的數目和位置決定。我想這應該是比較直觀的方法吧,但是這次看了Draw2D例子里的實現覺得也很有道理,以前沒想到過。在這個例子里樹節點圖形稱為TreeBranch,它包含一個PageNode(表現為帶有折角的矩形)和一個透明容器contentsPane,(一個Layer,用來放置子節點)。在一般情況下,TreeBranch本身使用名為NormalLayout的布局管理器將PageNode放在子節點的正上方,而contentsPane則使用名為TreeLayout的布局管理器計算每個子節點應在的位置。所以我們看到的整個樹實際上是由很多層子樹疊加而成的,任何一個非葉節點對應的圖形的尺寸都等于以它為根節點的子樹所占區域的大小。

    從這個例子里我們還看到,用戶可以選擇使用橫向或縱向組織樹(見圖2),可以壓縮各節點之間的空隙,每個節點可以橫向或縱向排列子節點,還可以展開或收起子節點,等等,這為我們實現一個方便好用的樹編輯器提供了良好的基礎(視圖部分的工作大大簡化了)。

    treevertical.gif
    圖2 縱向組織的樹

    這里要插一句,Draw2D例子中提供的這些類的具體內容我沒有仔細研究,相當于把它們當作Draw2D API的一部分來用了(包括TreeRoot、TreeBranch、TreeLayout、BranchLayout、NormalLayout、HangingLayout、PageNode等幾個類,把代碼拷到你的項目中即可使用),因為按照GEF 3.1的計劃表,它們很有可能以某種形式出現在正式版的GEF 3.1里。下面介紹一下我是如何把它們轉換為GEF應用程序的視圖部分從而實現樹編輯器的。

    首先從模型部分開始。因為樹是由一個個節點構成的,所以模型中最主要的就是節點類(我稱為TreeNode),它和例子里的TreeBranch圖形相對應,它應該至少包含nodes(子節點列表)和text(顯示文本)這兩個屬性;例子里有一個TreeRoot是TreeBranch的子類,用來表示根節點,在TreeRoot里多了一些屬性,如horizontal、majorSpacing等等用來控制整個樹的外觀,所以模型里也應該有一個繼承TreeNode的子類,而實際上這個類就應該是編輯器的contents,它對應的圖形TreeRoot也就是一般GEF應用程序里的畫布,這個地方要想想清楚。同時,雖然看起來節點間有線連接,但這里我們并不需要Connection對象,這些線是由布局管理器繪制的,畢竟我們并不需要手動改變線的走向。所以,模型部分就是這么簡單,當然別忘了要實現通知機制,下面看看都有哪些EditPart。

    與模型相對應,我們有TreeNodePart和TreeRootPart,后者和前者之間也是繼承關系。在getContentPane()方法里,要返回TreeBranch圖形所包含的contentsPane部分;在getModelChildren()方法里,要返回TreeNode的nodes屬性;在createFigure()方法里,TreeNodePart應返回TreeBranch實例,而TreeRootPart要覆蓋這個方法,返回TreeRoot實例;另外要注意在refreshVisuals()方法里,要把模型的當前屬性正確反映到圖形中,例如TreeNode里有反映節點當前是否展開的布爾變量expanded,則refreshVisuals()方法里一定要把這個屬性的當前值賦給圖形才可以。以下是TreeNodePart的部分代碼:

    public IFigure getContentPane() {
        
    return ((TreeBranch) getFigure()).getContentsPane();
    }


    protected List getModelChildren() {
        
    return ((TreeNode) getModel()).getNodes();
    }


    protected IFigure createFigure() {
        
    return new TreeBranch();
    }


    protected void createEditPolicies() {
        installEditPolicy(EditPolicy.COMPONENT_ROLE, 
    new TreeNodeEditPolicy());
        installEditPolicy(EditPolicy.LAYOUT_ROLE, 
    new TreeNodeLayoutEditPolicy());
        installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, 
    new ContainerHighlightEditPolicy());
    }

    上面代碼中用到了幾個EditPolicy,這里說一下它們各自的用途。實際上,從Role中已經可以看出來,TreeNodeEditPolicy是用來負責節點的刪除,沒有什么特別;TreeNodeLayoutEditPolicy則復雜一些,我把它實現為ConstrainedLayoutEditPolicy的一個子類,并實現createAddCommand()和getCreateCommand()方法,分別返回改變節點的父節點和創建新節點的命令,另外我讓createChildEditPolicy()方法返回NonResizableEditPolicy的實例,并覆蓋其createSelectionHandles()方法如下,以便在用戶選中一個節點時用一個控制點表示選中狀態,不用缺省邊框的原因是,邊框會將整個子樹包住,不夠美觀,并且在多選的時候界面比較混亂。

    protected List createSelectionHandles() {
        List list
    =new ArrayList();
        list.add(
    new ResizeHandle((GraphicalEditPart)getHost(), PositionConstants.NORTH));
        
    return list;
    }

    選中節點的效果如下圖,我根據需要改變了樹節點的顯示(修改PageNode類):

    treeselection.gif
    圖3 同時選中三個節點(Node2、Node3和Node8)

    最后一個ContainerHighlightEditPolicy的唯一作用是當用戶拖動節點到另一個節點區域中時,加亮顯示后者,方便用戶做出是否應該放開鼠標的選擇。它是GraphicalEditPolicy的子類,部分代碼如下,如果你看過Logic例子的話,應該不難發現這個類就是我從那里拿過來然后修改一下得到的。

    protected void showHighlight() {
        ((TreeBranch) getContainerFigure()).setSelected(
    true);
    }


    public void eraseTargetFeedback(Request request) {
        ((TreeBranch) getContainerFigure()).setSelected(
    false);
    }

    好了,現在樹編輯器應該已經能夠工作了。為了讓用戶使用更方便,你可以實現展開/收起子節點、橫向/縱向排列子節點等等功能,在視圖部分Draw2D的例子代碼已經內置了這些功能,你要做的就是給模型增加適當的屬性。我這里的一個截圖如下所示,其中Node1是收起狀態,Node6縱向排列子節點(以節省橫向空間)。

    treeeditor.gif
    圖4 樹編輯器的運行界面

    這個編輯器我花一天時間就完成了,但如果不是利用Draw2D的例子,相信至少要四至六天,而且缺陷會比較多,功能上也不會這么完善。我感覺在GEF中遇到沒有實現過的功能前最好先找一找有沒有可以利用的資源,比如GEF提供的幾個例子就很好,當然首先要理解它們才談得上利用。

    posted on 2005-05-27 00:09 八進制 閱讀(2028) 評論(20)  編輯 收藏 收藏至365Key 所屬分類: Eclipse

    評論

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-06-21 20:00 freegoldlu
    請問 這里例子的代碼 能mail給我嗎freegoldlu@sohu.com
    不方便的話 能不能把draw2d的例子代碼發一份 非常感謝 :)
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-06-22 20:30 八進制
    例子代碼確實不方便外傳,否則我都會提供下載鏈接的,見諒。
    draw2d例子已發郵箱,請查收。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-06-23 14:42 freegoldlu
    非常感謝你的答復,請教一個技術問題 按照你的文檔
    整個這個畫布的figure應該是roottree,我的畫布是merlin 自動generate 的 EDiagramEditPart, 我在里面
    protected IFigure createFigure() {
    //FigureCanvas treeroot=new FigureCanvas(this.getViewer().getControl().getShell());
    //treeroot.setBounds(0,0,200,200);
    //treeroot.setBackground(ColorConstants.white);
    TreeRoot root=new TreeRoot(createPageNode("Graph Root"));
    root.setBounds(new Rectangle(100,100,100,100));
    //treeroot.setContents(root);
    return root;
    }
    總是 出異常,請問 畫布 的figure應該怎么設置 謝謝
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-06-23 18:23 八進制
    不好說,最好把異常信息貼一下,并且說明在哪句出的異常。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-05 13:59 vicstart
    能否給個draw2d的例子代碼?
    vicstart@gmail.com
    謝謝
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-05 17:30 dorothy
    Could you send me the draw2d example too as fast as possible?
    Thank you so much! ^_^

    Regards,
    dorothyhelene@hotmail.fr
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-05 21:49 八進制
    vicstart&dorothy:Draw2D的例子可以從eclipse的cvs里獲得。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-06 17:08 dorothy
    Thank you for the information, in fact, I've found the example in eclipse cvs, I just wonder that we will have to download all the files in the directories of cvsviewer one by one by hand? or there is a better and simpler way to download the whole directory in the very same time? you see, how precious our time is! Maybe ask from you directly is a better choice, that's I did yesterday. :)

    Thanks a lot for answering to the silly question.

    have a good day.
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-06 17:15 dorothy
    sorry I forgot, good evening. :)
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-06 21:48 八進制
    dorothy:不客氣??梢韵螺d整個目錄,不知道你用的是什么工具,我是用eclipse自帶的cvs客戶端,選中要下載的目錄再check out即可。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-07 15:22 dorothy
    呵呵,終于裝了中文輸入法了,還是這樣講話比較親切。:)

    我剛用了一個月零幾天的eclipse,還不知道用cvs呢. :P

    多謝八進制了,以后還請多多指教!^_^
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-07-13 20:14 Bankey
    也發個例子給我好嗎
    fengbinhua@163.com
    謝謝

      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-03 11:53 fkpwolf
    看了你的很多文章,問個問題下,如何把GEF的圖存為XML文件格式?我都沒有找到相關方面的文檔。
    另:不知樓主用過jgraph沒有,能不能比較下,哈哈
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-03 21:33 八進制
    是指把GEF的模型保存為XML格式吧,用dom自己實現就可以了,或者如果你用EMF做模型,它提供了缺省的XML方式。還有很多工具可以實現。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-04 11:14 fkpwolf
    怎么把圖的所有信息存在XML文件中呢?這樣GEF就可以打開一個XML文件格式的圖。GEF帶的shape example做法是序列化為二進制了。EMF好像很復雜,有方便的工具嗎?
    多謝
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-04 21:23 八進制
    保存的工作不是gef負責,在editor的dosave里由你自己實現,序列化是一種方式,想存為xml用dom或其他工具重寫dosave方法。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-08 09:15 fkpwolf
    多謝提醒,現在利用eclopse.org上面的EMF + GEF已經可以存為XML了。但是當我后來在MODEL中加了一個類Action,并在Shape中引用它(多個),編輯完Shape后,保存,報異常:
    org.eclipse.emf.ecore.xmi.DanglingHREFException: The object 'org.eclipse.gef.examples.shapes.emf.model.impl.ActionImpl@1a503f (description: wokao)' is not contained in a resource. at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.handleDanglingHREF(XMLHelperImpl.java:644)
    對EMF不熟悉,不知道如何處理。
    多謝
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-08 20:37 八進制
    在Shape中是怎樣引用Action類的?
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-09 08:51 fkpwolf
    我是在“Sample Ecore Model Editor”中打開modle.ecore文件(原來例子的),在其中添加一個EClass:Action,然后在Shape中引用它(跟引用Connection一樣),然后產生出類出來,沒有作其他處理。
      

    # re: [Eclipse]GEF入門系列(十一、樹的一個實現) 2005-08-12 09:00 fkpwolf
    弄了半天是引用的containment熟悉應該設置為true,55555
    posted on 2005-08-26 17:16 sharky的點滴積累 閱讀(761) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲一区中文字幕在线观看| 精品国产综合成人亚洲区| 亚洲欧洲日韩综合| 中文字幕视频免费| 亚洲精品高清国产麻豆专区| 最近免费最新高清中文字幕韩国 | 亚洲 自拍 另类小说综合图区| 亚洲欧美国产国产综合一区| 天天拍拍天天爽免费视频| 亚洲性无码AV中文字幕| 国产免费观看网站| 一区二区视频在线免费观看| 精品亚洲一区二区三区在线观看| 久久精品成人免费国产片小草| 国产精品久久久亚洲| 亚洲精品免费视频| 2020国产精品亚洲综合网| 日韩高清在线免费看| www在线观看免费视频| 亚洲国产综合无码一区| 2021在线观看视频精品免费| 亚洲一级高清在线中文字幕| 免费鲁丝片一级观看| 一级A毛片免费观看久久精品| 亚洲AV无码一区东京热| 野花高清在线观看免费3中文 | 亚洲一级毛片在线观| 免费观看男人免费桶女人视频| 人人公开免费超级碰碰碰视频 | 91精品啪在线观看国产线免费| 亚洲一区二区三区在线网站| 国产一级淫片免费播放电影| 中文字字幕在线高清免费电影| 亚洲最新中文字幕| 亚洲精品国产日韩无码AV永久免费网 | 最近免费中文字幕大全视频| 美女免费视频一区二区三区| 久久亚洲国产精品一区二区| 好男人看视频免费2019中文| 99re6在线视频精品免费| 亚洲色大成网站www尤物|