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

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

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

    蘋果的成長日記

    我還是個青蘋果呀!

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      57 隨筆 :: 0 文章 :: 74 評論 :: 0 Trackbacks
    GEF入門系列(四、其他功能)

    最近由于實驗室任務繁重,一直沒有繼續研究GEF,本來已經掌握的一些東西好象又丟掉了不少,真是無奈啊,看來還是要經常碰碰。剛剛接觸GEF的朋友大都會有這樣的印象:GEF里概念太多,比較繞,一些能直接實現的功能非要拐幾個彎到另一個類里做,而且很多類的名字十分相似,加上不知道他們的作用,感覺就好象一團亂麻。我覺得這種情況是由圖形用戶界面(GUI)的復雜性所決定的,GUI看似簡單,實際上包含了相當多的邏輯,特別是GEF處理的這種圖形編輯方式,可以說是最復雜的一種。GEF里每一個類,應該說都有它存在的理由,我們要盡可能了解作者的意圖,這就需要多看文檔和好的例子。

    在Eclipse里查看文檔和代碼相當便利,比如我們對某個類的用法不清楚,一般首先找它的注釋(選中類或方法按F2),其次可以查看它在其他地方用法(選中類或方法按Ctrl+Shift+G),還可以找它的源代碼(Ctrl+鼠標左鍵或F3)來看,另外Ctrl+Shift+T可以按名稱查找一個類等等。學GEF是少不了看代碼的,當然還需要時間和耐心。

    好,閑話少說,下面進入正題。這篇帖子將繼續上一篇內容,主要討論如何實現DirectEdit、屬性頁和大綱視圖,這些都是一個完整GEF應用程序需要提供的基本功能。

    實現DirectEdit

    所謂DirectEdit(也稱In-Place-Edit),就是允許用戶在原本顯示內容的地方直接對內容進行修改,例如在Windows資源管理器里選中一個文件,然后按F2鍵就可以開始修改文件名。實現DirectEdit的原理很直接:當用戶發出修改請求(REQ_DIRECT_EDIT)時,就在文字內容所在位置覆蓋一個文本框(也可以是下拉框,這里我們只討論文本的情況)作為編輯器,編輯結束后,再將編輯器中的內容應用到模型里即可。(作為類似的功能請參考:給表格的單元格增加編輯功能

    directedit.gif
    圖1 Direct Edit

    在GEF里,這個彈出的編輯器由DirectEditManager類負責管理,在我們的NodePart類里,通過覆蓋performRequest()方法響應用戶的DirectEdit請求,在這個方法里一般要構造一個DirectEditManager類的實例(例子中的NodeDirectEditManager),并傳入必要的參數,包括接受請求的EditPart(就是自己,this)、編輯器類型(使用TextCellEditor)以及用來定位編輯器的CellEditorLocator(NodeCellEditorLocator),然后用show()方法使編輯器顯示出來,而編輯器中顯示的內容已經在構造方法里得到。簡單看一下NodeCellEditorLocator類,它的關鍵方法在relocate()里,當編輯器里的內容改變時,這個方法被調用從而讓編輯器始終處于正確的坐標位置。DirectEditManager有一個重要的initCellEditor()方法,它的主要作用是設置編輯器的初始值。在我們的例子里,初始值設置為被編輯NodePart對應模型 (Node)的name屬性值;這里還另外完成了設置編輯器字體和選中全部文字(selectAll)的功能,因為這樣更符合一般使用習慣。

    在NodePart里還要增加一個角色為DIRECT_EDIT_ROLE的EditPolicy,它應該繼承自DirectEditPolicy,有兩個方法需要實現:getDirectEditCommand()和showCurrentEditValue(),雖然還未遇到過,但前者的作用你不應該感到陌生--在編輯結束時生成一個Command對象將修改結果作用到模型;后者的目的是更新Figure中的顯示,雖然我們的編輯器覆蓋了Figure中的文本,似乎并不需要管Figure的顯示,但在編輯中時刻保持這兩個文本的一致才不會出現"蓋不住"的情況,例如當編輯器里的文本較短時。

    實現屬性頁

    在GEF里實現屬性頁和普通應用程序基本一樣,例如我們希望可以通過屬性視圖(PropertyView)顯示和編輯每個節點的屬性,則可以讓Node類實現IPropertySource接口,并通過一個IPropertyDescriptor[]類型的成員變量描述要在屬性視圖里顯示的那些屬性。有朋友問,要在屬性頁里增加一個屬性都該改哪些地方,主要是三個地方:首先要在你的IPropertyDescriptor[]變量里增加對應的描述,包括屬性名和屬性編輯方式(比如文本或是下拉框,如果是后者還要指定選項列表),其次是getPropertyValue()和setPropertyValue()里增加讀取屬性值和將結果寫入的代碼,這兩個方法里一般都是像下面的結構(以前者為例):

    public Object getPropertyValue(Object id) {
        
    if (PROP_NAME.equals(id))
            
    return getName();
        
    if (PROP_VISIBLE.equals(id))
            
    return isVisible() ? new Integer(0) : new Integer(1);
        
    return null;
    }

    也就是根據要處理的屬性名做不同操作。要注意的是,下拉框類型的編輯器是以Integer類型數據代表選中項序號的,而不是int或String,例如上面的代碼根據visible屬性返回第零項或第一項,否則會出現ClassCastException。

    properties.gif
    圖2 屬性頁

    實現大綱視圖

    在Eclipse里,當編輯器(Editor)被激活時,大綱視圖自動通過這個編輯器的getAdapter()方法尋找它提供的大綱(大綱實現IcontentOutlinePage接口)。GEF提供了ContentOutlinePage類用來實現大綱視圖,我們要做的就是實現一個它的子類,并重點實現createControl()方法。ContentOutlinePage是org.eclipse.ui.part.Page的一個子類,大綱視圖則是PageBookView的子類,在大綱視圖中有一個PageBook,包含了很多Page并可以在它們之間切換,切換的依據就是當前活動的Editor。因此,我們在createControl()方法里要做的就是構造這個Page,簡化后的代碼如下所示:

    private Control outline;
    public OutlinePage() {
        super(
    new TreeViewer());
    }
    public 
    void createControl(Composite parent) {
        outline 
    = getViewer().createControl(parent);
        getSelectionSynchronizer().addViewer(getViewer());
        getViewer().setEditDomain(getEditDomain());
        getViewer().setEditPartFactory(
    new TreePartFactory());
        getViewer().setContents(getDiagram());
    }

    由于我們在構造方法里指定了使用樹結構顯示大綱,所以createControl()里的第一句就會使outline變量得到一個Tree(見org.eclipse.gef.ui.parts.TreeViewer的代碼),第二句把TreeViewer加到選擇同步器中,從而讓用戶不論在大綱或編輯區域里選擇EditPart時,另一方都能自動做出同樣的選擇;最后三行的作用在以前的帖子里都有介紹,總體目的是把大綱視圖的模型與編輯區域的模型聯系在一起,這樣,對于同一個模型我們就有了兩個視圖,體會到MVC的好處了吧。

    實現大綱視圖最重要的工作基本就是這些,但還沒有完,我們要在init()方法里綁定UNDO/REDO/DELETE等命令到Eclipse主窗口,否則當大綱視圖處于活動狀態時,主工具條上的這些命令就會變為不可用狀態;在 getControl()方法里要返回我們的outline成員變量,也就是指定讓這個控件出現在大綱視圖中;在dispose()方法里應該把這個TreeViewer從選擇同步器中移除;最后,必須在PracticeEditor里覆蓋getAdapter()方法,前面說過,這個方法是在Editor激活時被大綱視圖調用的,所以在這里必須把我們實現好的OutlinePage返回給大綱視圖使用,代碼如下:

    public Object getAdapter(Class type) {
        
    if (type == IContentOutlinePage.class)
            
    return new OutlinePage();
        
    return super.getAdapter(type);
    }

    這樣,樹型大綱視圖就完成了,見下圖。很多GEF應用程序同時具有樹型和縮略圖兩種大綱,實現的基本思路是一樣的,但代碼會稍微復雜一些,因為這兩種大綱一般要通過一個PageBook進行切換,縮略圖一般由org.eclipse.draw2d.parts.ScrollableThumbnail負責實現,這里暫時不講了(也許以后會詳細說),你也可以通過看logic例子的LogicEditor這個類的代碼來了解。

    outline.gif
    圖3 大綱視圖

    P.S.寫這篇帖子的時候,我對例子又做了一些修改,都是和這篇帖子所說的內容相關的,所以如果你以前下載過,會發現那時的代碼與現在稍有不同(功能還是完全一樣的,下載)。另外要說一下,這個例子并不完善,比如刪除一個節點的時候,它的連接就沒同時刪除,一些鍵盤快捷鍵不起作用,還存在很多被注釋掉的代碼等等。如果有興趣你可以來修改它們,也是不錯的學習途徑。

    posted on 2005-06-22 14:35 蘋果 閱讀(416) 評論(0)  編輯  收藏 所屬分類: J2EE/JAVA學習
    主站蜘蛛池模板: 国产午夜亚洲精品不卡| 日本黄色动图免费在线观看| 亚洲精品和日本精品| 中文字幕版免费电影网站| 在线观看亚洲人成网站| 日韩成人在线免费视频| 91成人免费观看在线观看| 亚洲女人影院想要爱| 亚洲AV无码之日韩精品| 91精品全国免费观看含羞草| 亚洲1区2区3区精华液| 亚洲AV综合色区无码一区爱AV| 黄页网站免费在线观看| 思思久久99热免费精品6| 久久久久亚洲精品天堂| 免费一级肉体全黄毛片| 69精品免费视频| 一级中文字幕免费乱码专区| 亚洲日韩在线视频| 中文字幕无码精品亚洲资源网| 无码av免费毛片一区二区| 国产无遮挡又黄又爽免费网站 | 亚洲国产精品嫩草影院 | 国产午夜亚洲精品不卡| 亚洲最新视频在线观看| 免费看国产一级片| 无码国产精品一区二区免费式直播 | 国产在线ts人妖免费视频| 美女内射毛片在线看免费人动物| 爱情岛论坛免费视频| 性xxxx黑人与亚洲| 亚洲成人在线网站| 在线观看国产区亚洲一区成人| 成人免费看片又大又黄| 久章草在线精品视频免费观看| 男女作爱免费网站| 亚洲av永久中文无码精品| 亚洲国产成人久久99精品| 亚洲国产精品无码av| 亚洲欧洲久久av| 又爽又黄无遮挡高清免费视频|