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

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

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

    月蝕傳說

    浮躁讓人失去理智
    posts - 25, comments - 101, trackbacks - 0, articles - 0
      BlogJava :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理

    數(shù)據(jù)庫字段的顯示以及增加

    Posted on 2006-10-09 19:02 Dart 閱讀(3958) 評論(5)  編輯  收藏 所屬分類: GEF

    隔了將近一個月,我終于可以在家上網(wǎng)了——我又回來了。由于搬家后沒有網(wǎng)上,本來這篇應(yīng)該早就寫完的文章也只能拖了這么久才“發(fā)布”。

    在這一章,我說一下如何去利用布局,以及其他一些關(guān)于EditPolicy的用法和Palette的實(shí)現(xiàn)。說明一下,示例代碼和本章內(nèi)容中的代碼有出入,這是因?yàn)橐郧拔沂亲鲆稽c(diǎn)寫一點(diǎn),這次我完成得比較多,但是由于涉及技術(shù)有一些差異,所以我將分成兩篇文章講完,我建議大家看完第5章后再下代碼。代碼下載.

    1.重新顯示TableFigure

    上一章中,我們簡單地繪制了一個矩形,充當(dāng)我們的數(shù)據(jù)庫表的圖形,現(xiàn)在讓我們重新想想,如何顯示這個TableFigure。

    讓我們看看Visio里面是怎么顯示的吧:



    我們也按照它的樣子做一個類似的!

    首先,我們需要顯示我們的表名,其次,我們要將數(shù)據(jù)字段顯示在表名下放的區(qū)域中,然后再在表名和存放數(shù)據(jù)庫字段的區(qū)域之間畫一條線,分割開。看下圖:


    看來我們以前寫的TableFigure還差太遠(yuǎn),僅僅一個矩形還不夠。

    先考慮一下如何顯示表名。在TableFigure中顯示一條文字很容易的,簡單的方法就是在繪制它的時候,利用Graphics的drawText方法即可,但是這樣做很繁瑣,需要不停的計算表名顯示位置,并且,當(dāng)我們的表名發(fā)生改變的時候,表自身大小該如何調(diào)節(jié)呢。所以我們需要利用Label來顯示,因?yàn)長abel可以很容易地對顯示的表名進(jìn)行維護(hù),包括計算文字長度獲得Figure該具有的大小等;此外,當(dāng)我們使用Label來顯示的話, TableFigure還可以通過布局管理器來計算自己當(dāng)前的大小,這又省得我們自己計算了。打開TableFigure類,增加以下代碼:

    public ?TableFigure(Table?model)?{
    ????????super();
    ????????
    this .model? = ?model;

    ????????tableNameLabel?
    = ? new ?Label();
    ????????tableNameLabel.setText(model.getTableName());
    ????????FontData?fd?
    = ? new ?FontData();

    ????????fd.setHeight(
    10 );
    ????????fd.setName(
    " Arial " );
    ????????fd.setStyle(SWT.BOLD);

    ????????tableNameLabel.setFont(
    new ?Font( null ,?fd));
    ????????tableNameLabel.setIcon(ImageProvider.TABLE_ICON.createImage());
    ????????tableNameLabel.setLabelAlignment(PositionConstants.MIDDLE);

    ????????
    // ?留出一點(diǎn)邊距,會好看點(diǎn)
    ???????? this .setBorder( new ?MarginBorder( 8 ,? 8 ,? 8 ,? 8 ));

    ????????
    this .add(tableNameLabel);
    ????????
    ????????
    this .setOpaque( true );
    ????}

    我們在TableFigure創(chuàng)建的時候,給它生成了一個Label,然后將這個Label作為TableFigure的子Figure添加到它上面,這樣一來我們就讓這個Label來顯示數(shù)據(jù)表名。上面代碼中用到了圖片設(shè)置以及字體設(shè)置,這里我們只討論GEF,所以就不討論他們了。

    名字能顯示了,現(xiàn)在該讓我們的字段容器出場了!

    字段的圖形需要有容器去維護(hù)顯示它,剛才我們也看到了,Visio中的字段都是在字段容器中自上而下有序地排列在一起的,問題就來了:怎么去讓它們?nèi)绱寺犜挼赜行蚺帕心亍2季止芾砥鳎↙ayoutManager),只要做過桌面應(yīng)用的人都知道,不錯,Draw2D也是利用布局管理器來對圖形進(jìn)行位置大小進(jìn)行維護(hù)的。在Draw2D中有一個名為ToolbarLayout的布局管理器,它實(shí)現(xiàn)了讓Figure自上而下有序地排列在一起,這正是我們需要的!

    現(xiàn)在讓我們在TableFigure構(gòu)造函數(shù)中增加以下代碼:

    ??????containerFigure? = ? new ?Figure()?;

    ????????ToolbarLayout?tableLayout?
    = ? new ?ToolbarLayout();
    ??
    ????????
    // ?承載Column?Figure的容器是ToolbarLayout
    ????????ToolbarLayout?containerLayout? = ? new ?ToolbarLayout();
    ????????containerLayout.setMinorAlignment(ToolbarLayout.ALIGN_BOTTOMRIGHT);
    ????????containerFigure.setLayoutManager(containerLayout);
    ?????
    ????????
    this .add(containerFigure);


    ??這樣我們的containerFigure就做好了。

    但是光這樣還不夠。containerFigure 和tableNamelable這兩個Figure作為TableFigure的子圖形,應(yīng)該顯示在哪兒呢?怎么給他們定位?而且,當(dāng)我們的這兩個子圖形大小發(fā)生改變了以后,TableFigure怎么辦?
    其實(shí)所有的一切問題都是由布局管理器來回答的。

    在Figure 類中有一個名位getPreferredSize的方法,這個方法是去獲得當(dāng)前Figure大小的。默認(rèn)的情況下,getPreferredSize方法會查看該Figure中是否注冊有布局管理器,如果有,那么就會調(diào)用布局管理器的getPreferredSize方法獲得大小。布局管理器的 getPreferredSize方法并不是簡單地去查看當(dāng)前Figure的Size,而是要通過該布局本身的特點(diǎn),再通過該Figure中的子圖形位置以及大小,按照一定的算法疊加而取得當(dāng)前Figure的大小。

    簡單說,如果我們使用了ToolbarLayout,那么當(dāng)我們調(diào)用注冊有該 LayoutManager的Figure的getPreferredSize方法時,布局管理器就會將該Figure的高度設(shè)置為它所有子Figure 的高度和;寬度設(shè)為所有子Figure中寬度最大值。

    這樣一來,根據(jù)我們剛才圖形所畫的那樣,tableNameFigure和 containerFigure也是自上而下排列的,所有,我們可以在TableFigure中使用ToolbarLayout,讓布局管理器來管理它的大小。寫到這里大家也都看出來了,我們在containerFigure中設(shè)置ToolbarLayout的,也是為了當(dāng)我們增加字段圖形的時候,讓布局管理器去控制它的大小。

    我們已經(jīng)基本完成了TableFigure。但是如果在我們添加了數(shù)據(jù)庫字段的時候,EditPart并不知道讓字段的Figure是作為TableFigure中containerFigure的子圖形而添加進(jìn)去的,它默認(rèn)是把字段圖形直接繪制到 TableFigure上,那這樣我們剛才的設(shè)想就完全實(shí)現(xiàn)不了了。所以,讓我們復(fù)寫TableEditPart的getContentPane方法:

    ? public ?IFigure?getContentPane()?{
    ????????
    return ?((TableFigure)getFigure()).getContainerFigure();
    ????}

    這是什么意思呢?
    在前面的章節(jié)我好像說過了,GEF中對于某一個EditPart,它的子EditPart的圖形是繪制在該EditPart的圖形之上的——一個遞歸的過程。但是EditPart并不是把它的圖形直接默認(rèn)為子Fiuger的容器Figure,而是通過getContentPane方法來獲得承載子 EditPart圖形的Figure,當(dāng)然,如果直接繼承GraphicalEditPart的話,getContentPane方法直接返回的就是 getFigure,所以,當(dāng)我們要重新定義EditPart的容器Figure的時候,就需要復(fù)寫getContentPane。





    2.顯示出ColumnFigure

    現(xiàn)在我們來實(shí)現(xiàn)字段圖形。
    字段圖形很簡單,只要實(shí)現(xiàn)字段名以及一個能表示字段的圖標(biāo)即可,所以我們將它繼承自Label:

    public ? class ?ColumnFigure?extends?Label?{
    ????
    private ?Column?model;
    ????
    private ?boolean?selected;
    ????
    private ?boolean?hasFocus;
    ??????
    public ?ColumnFigure(Column?model){
    ??????????super();
    ??????????
    this .model? = ?model;
    ??????????model.setColumnName(model.getColumnName());
    ??????????
    ??????????FontData?fd?
    = ? new ?FontData();
    ??????????
    ????????????fd.setHeight(
    8 );
    ????????????fd.setName(
    " Arial " );
    ????????????fd.setStyle(SWT.BOLD);
    ??????????
    this .setIcon(ImageProvider.COLUMN_ICON.createImage());
    ??????????
    this .setLabelAlignment(PositionConstants.LEFT);
    ??????????
    this .setFont( new ?Font( null ,fd));
    ??????}
    }

    然后讓ColumnEditPart的createFigure方法返回它:

    ????protected?IFigure?createFigure()?{
    ????????
    //?TODO?Auto-generated?method?stub
    ????????return?new?ColumnFigure((Column)getModel());
    ????}

    ok,現(xiàn)在讓我們在DbEditor中修改一下initializeGraphicalViewer方法:

    protected?void?initializeGraphicalViewer()?{
    ????????
    //?硬編碼生成一個數(shù)據(jù)庫模型
    ????????Schema?schema?=?new?Schema();
    ????????Table?table?
    =?new?Table();
    ????????table.setTableName(
    "Test");
    ????????Column?column?
    =?new?Column();
    ????????column.setColumnName(
    "test");
    ????????table.addChild(column);
    ????????schema.addChild(table);
    ????????
    this.getGraphicalViewer().setContents(schema);
    ????}

    OK,現(xiàn)在我們可以看到一個新的TableFigure了。

    但是存在一個問題:我們的TableFigure大小自己不能計算獲得,連字段都沒顯示出來。肯定有人要說了:不是說有了布局管理器就可以了嗎!

    等等,還記得上一章中,我們?yōu)榱四芤苿泳匦危鴱?fù)寫了refreshVisuals方法吧?現(xiàn)在我們重新寫一遍:

    ?protected?void?refreshVisuals()?{
    ????????super.refreshVisuals();
    ????????
    //?得到當(dāng)前TableFigure的大小,由于有Toolbar布局的約束,它會自動計算
    ???????
    ????????Dimension?size?
    =?this.getFigure().getPreferredSize();
    ????????
    ????????
    //?獲得更改后的位置,位置是在Model進(jìn)行維護(hù)的
    ????????Point?p?=?((Table)?getModel()).getLocation();
    ????????
    ????????
    //?我們只更改Table的位置
    ????????((GraphicalEditPart)?this.getParent()).setLayoutConstraint(this,?this
    ????????????????.getFigure(),
    new?Rectangle(p,?size));
    ????}


    看過以前代碼的朋友一眼就發(fā)現(xiàn)了不同:size不再是簡單的去取得當(dāng)前的bounds大小了,而是通過我們上面說的,利用getPreferredSize方法去讓布局計算!

    修改完畢后再看看我們的TableFigure:




    補(bǔ)充一下:篇幅問題,我只撿我認(rèn)為重要的說,其他的一些細(xì)節(jié),比如,TableFigure尺寸最大和最小約束啊,怎么畫tableNameLabel下的線啊,還有Label的停靠啊,border的使用啊,漸變矩形的繪制啊,這些我就沒有提起了,大家可以自己看代碼,如果有疑問可以發(fā)貼討論。

    3.重新生成PaletteRoot

    在我們以前的例子中,工具面板生成的是一個很簡單的空面板,上面光禿禿的,無法通過面板的工具往我們的Viewer中增加Figure圖形,使得我們每次都需要在DbEditor中復(fù)寫修改代碼,用硬編碼來實(shí)現(xiàn)模型的增加。

    現(xiàn)在起我們要構(gòu)造一個可以創(chuàng)建Table和Column的工具面板,讓硬編碼創(chuàng)建模型見鬼去吧。

    先生成一個單態(tài)類:PaletteFactory,然后在我們在里面生成一個空的PaletteRoot,再弄兩個PaletteDrawer添加到PaletteRoot上:

    public?class?PaletteFactory?{
    ????
    ????
    private?PaletteRoot?root;
    ????
    ????
    private?PaletteDrawer?defaultTools;
    ????
    ????
    private?PaletteDrawer?dbTools;
    ????
    ????
    private?static?PaletteFactory?instance?=?null;
    ????
    private?PaletteFactory(){}
    ????
    ????
    public?static?PaletteFactory?INSTANCE(){
    ????????
    if(instance?==?null)?instance?=?new?PaletteFactory();
    ????????
    return?instance;
    ????}
    ????
    ????
    public?PaletteRoot?createPaletteRoot(){
    //????????if(root?!=?null)?return?root;
    ????????
    ????????root?
    =?new?PaletteRoot();
    ????????root.add(createDefaultToolBox());
    ????????root.add(createDbToolBox());
    ????????
    return?root;
    ????}
    ????
    ????
    private?PaletteDrawer?createDefaultToolBox(){
    ????????defaultTools?
    =?new?PaletteDrawer("Default?tools");
    ????????
    ????????defaultTools.add(
    new?SelectionToolEntry());
    ????????
    ????????
    return?defaultTools;
    ????}
    ????
    ????
    private?PaletteDrawer?createDbToolBox(){
    ????????dbTools?
    =?new?PaletteDrawer("DataBase?tools");????????
    ????????
    return?dbTools;
    ????}
    }

    我簡單說一下,PaletteDrawer是一種可以隱藏的容器,在它上面可以增加按鈕等ToolEntry。什么是ToolEntry呢?大家可以理解為在Palette上面的任何元素:按鈕、分割線、容器等,ToolEntry對應(yīng)有一個Tool,通過ToolEntry的createTool返回的,如果我們需要一些特別處理的時候,可以直接去實(shí)現(xiàn)ToolEntry和Tool,但是在我們的例子中,我們需要的是可以生成模型的ToolEntry,所以我們就不必去研究ToolEntry和Tool的工作原理。


    接著往下說。
    上述代碼中,我們給defaultTools容器增加了一個SelectionToolEntry,它是GEF自己提供的一個工具,是為點(diǎn)擊選擇圖形使用的,對于它的作用這里就不廢話了:)

    從代碼下面可以看出來,我們還沒有增加創(chuàng)建Table和Column的ToolEntry,現(xiàn)在我們來實(shí)現(xiàn)他們。

    創(chuàng)建兩個ToolEntry,分別命名為TableToolEntry和ColumnToolEntry,他們都是繼承了 CreationToolEntry。注意一下CreationToolEntry的構(gòu)造函數(shù),需要傳入一個CreationFactory,這個工廠類就是創(chuàng)建我們所要返回的模型實(shí)例工廠,它的兩個方法:getNewObject()和getObjectType()分別是返回創(chuàng)建的模型和模型的類型。

    來看看我們的對該工廠的實(shí)現(xiàn):

    public?class?DbCreationFactory?implements?CreationFactory?{

    ????
    private?Class?type;
    ????
    public?DbCreationFactory(Class?type){
    ????????setType(type);
    ????}

    ????
    public?Object?getNewObject()?{
    ????????
    if(type?==?Table.class){
    ????????????
    return?new?Table();
    ????????}
    ????????
    if(type?==?Column.class)?return?new?Column();
    ????????
    return?null;
    ????}

    ????
    public?Object?getObjectType()?{
    ????????
    //?TODO?Auto-generated?method?stub
    ????????return?getType();
    ????}
    ??? .......
    }

    通過創(chuàng)建這個工 廠類的時候傳入的參數(shù),就可以生成對應(yīng)的模型了

    再看看我們的TableToolEntry和 ColumnToolEntry的實(shí)現(xiàn)的:
    public?class?TableToolEntry?extends?CreationToolEntry?{
    ????
    public?TableToolEntry()?{
    ????????super(
    "Table",?"Create?a?table",?new?DbCreationFactory(Table.class),?ImageProvider.TABLE_ICON,?null);
    ????}
    }


    public?class?ColumnToolEntry?extends?CreationToolEntry?{
    ????
    public?ColumnToolEntry(){
    ????????super(
    "Column",?"Create?a?column",?new?DbCreationFactory(Column.class),?ImageProvider.COLUMN_ICON,?null);
    ????}
    }< /span>

    大家看出來了,我們傳入的DbCreationFactory 都是對應(yīng)了他們所要生成模型需要的參數(shù)。

    現(xiàn)在,我們的ToolEntry類創(chuàng)建好了,讓我們把它們添加到 dbTools的PaletteDrawer上:

    修改?PaletteFactory 類的 createDbToolBox()方法
    ????private?PaletteDrawer?createDbToolBox(){
    ????????dbTools?
    =?new?PaletteDrawer("DataBase?tools");
    ????????
    ????????dbTools.add(
    new?TableToolEntry());
    ?????????dbTools.add(new ColumnToolEntry());
    ?????
    ????????
    return?dbTools;
    ????}


    運(yùn)行一下:



    4.新的Command; FlowEditPolicy的用法

    完成了上面的工作后,我們離從工具面板上創(chuàng)建模型還差點(diǎn):EditPolicy中沒有對應(yīng)的Command。

    以前的章節(jié)里,我們都知道了,GEF中的所有事件都封裝成了Request向外發(fā)送,然后找到EditPolicy處理,EditPolicy再去索取Command來執(zhí)行。我們在上一章就已經(jīng)生成了一個TableMoveCommand,所以相信大家對Command應(yīng)該不陌生了。

    我們生成這樣一個Command:DbItemCreationCommand

    public?class?DbItemCreateCommand?extends?Command?{
    ????
    private?DBBase?parent;
    ????
    private?DBBase?child;
    ????
    private?int?index?=?-1;
    ????

    ????
    public?void?execute()?{
    ????????Assert.isNotNull(parent);
    ????????Assert.isNotNull(child);
    ????????parent.addChild(index,child);
    ????}

    ????
    public?void?redo()?{
    ????????execute();
    ????}

    ????
    public?void?undo()?{
    ????????Assert.isNotNull(parent);
    ????????Assert.isNotNull(child);
    ????????parent.removeChild(child);
    ????}
    ......
    ??......

    }

    現(xiàn)在,有了這個Command,我們就要考慮一下,看講它交給誰的EditPolicy去返回。




    通常情況下,如果我們要生成一個模型,那么我們就應(yīng)該在它的父容器的EditPolicy注冊一個 Command,因?yàn)榻^大多數(shù)的容器類型的EditPart,都有安裝有ContainerEditPolicy或者LayoutEditPolicy,而這兩種EditPolicy恰恰就能對CreateRequest進(jìn)行截獲并進(jìn)行處理。所以,結(jié)合我們的例子,要生成Table模型,就需要在他的父 EditPart——SchemaEditPart的SchemaLayoutEditPolicy里做文章。

    打開這個類,發(fā)現(xiàn)里面有一個方法:getCreateCommand,我們就在這里面返回DbItemCreateCommand吧:

    protected?Command?getCreateCommand(CreateRequest?request)?{
    ????????Object?obj?
    =?request.getNewObject();
    ????????
    if(obj?!=?null?&&?request.getNewObjectType()?==?Table.class){
    ????????????DbItemCreateCommand?command?
    =?new?DbItemCreateCommand();
    ????????????command.setParent((DBBase)
    this.getHost().getModel());
    ????????????command.setChild((DBBase)obj);
    ????????????((Table)obj).setLocation(request.getLocation());
    ????????????
    return?command;
    ????????}
    ????????
    return?null;
    ????}

    看看上面的代碼,發(fā)現(xiàn)了嗎?CreateRequest攜帶有我們要生成的對象的類型以及實(shí)例,并且連我們在創(chuàng)建時點(diǎn)擊在Viewer上的位置也有,所以,我們只需要設(shè)置一下DbItemCreateCommand中的父模型以及子模型即可,當(dāng)然,我們還需要在生成模型的時候,將生成該模型時鼠標(biāo)所點(diǎn)擊的位置給Table模型,好讓他一創(chuàng)建就處在該位置。太cool了!

    但是光是添加了模型,EditPart是不知道的,所以我需要去通知EditPart刷新一下。還記得上一章中,矩形位置更改后是怎么通知EditPart的嗎?我再羅嗦一下吧:利用我們在模型中的PropertyChangeSupport發(fā)出屬性更改通知,然后然EditPart截獲后去做相應(yīng)的動作即可:

    更改DBBase部分代碼代碼:
    public?void?addChild(int?index?,?DBBase?child){
    ????????
    if(index?==?-1){
    ????????getChildren().add(child);
    ????????}
    else{
    ????????????getChildren().add(index,child);
    ????????}
    ????????child.setParent(
    this);
    ????????
    this.fireChildenChange(child);
    ????}
    ????
    ????
    public?void?removeChild(DBBase?child){
    ????????child.setParent(
    null);
    ????????getChildren().remove(child);
    ????????
    this.fireChildenChange(child);
    ????}

    ????
    public?void?fireChildenChange(DBBase?child){
    ????????support.firePropertyChange(PRO_CHILD,
    null,child);
    ????}


    讓DBEditPartBase去截獲PRO_CHILD事件:
    ?public?void?propertyChange(PropertyChangeEvent?evt)?{
    ???????String?pName?
    =?evt.getPropertyName();

    ???????if(pName.equals(DBBase.PRO_CHILD)){
    ???????????
    this.refreshChildren();
    ???????????
    this.refreshVisuals();
    ???????}
    ????}

    最后讓我們把以前在DbEditor中生成模型的代碼刪除掉,就讓Viewer的Content設(shè)置為一個Schema即可,
    好了,運(yùn)行一下吧,是不是可以創(chuàng)建Table了?:)

    5.FlowLayoutEditPolicy的應(yīng)用以及Column的創(chuàng)建

    我們已經(jīng)能夠創(chuàng)建Table了,現(xiàn)在需要創(chuàng)建一個Column。

    在上面我們已經(jīng)創(chuàng)造了生成Column模型的條件:ColumnToolEntry、DbCreateFactory還有DbItemCreateCommand,就差一樣:我們把這個Command往哪兒放呢?

    以前的經(jīng)驗(yàn)告訴我們,這個Command是需要讓ColumnEditPart的父EditPart的EditPolicy去返回的,但是它的父 EditPart,也是就TableEditPart,目前沒有安裝能夠維護(hù)創(chuàng)建子模型的EditPolicy,所以我們需要創(chuàng)建一個給他安裝上。

    我們選用一個名為FlowLayoutEditPolicy的類作為我們新建EditPolicy的父類,這是因?yàn)?FlowLayoutEditPolicy專門針對具有FlowLayout以及ToolbarLayout布局管理器的Figure而做的,它可以對子 Figure的位置移動做出一些維護(hù),比如當(dāng)我們在TableFigure中拖動了ColumnFigure,F(xiàn)lowLayoutEditPolicy 可以在它可以插入的位置顯示一條黑線:



    我們的這個類就命名為TableFlowLayoutEditPolicy:

    public?class?TableFlowLayoutEditPolicy?extends?FlowLayoutEditPolicy?{

    .......
    ?
    ????
    protected?Command?getCreateCommand(CreateRequest?request)?{
    ????????Object?obj?
    =?request.getNewObject();
    ????????
    if(obj?!=?null?&&?request.getNewObjectType()?==?Column.class){
    ????????????DbItemCreateCommand?command?
    =?new?DbItemCreateCommand();
    ????????????command.setParent((DBBase)
    this.getHost().getModel());
    ????????????command.setChild((DBBase)obj);
    ????????????
    ????????????EditPart?after?
    =?getInsertionReference(request);
    ????????????
    int?index?=?getHost().getChildren().indexOf(after);
    ????????????command.setIndex(index);
    ????????????
    return?command;
    ????????}
    ????????
    return?null;
    ????}
    ? .......
    ?............
    ????
    protected?boolean?isHorizontal()?{
    ????????IFigure?figure?
    =?((GraphicalEditPart)getHost()).getContentPane();
    ????????LayoutManager?layout?
    =?figure.getLayoutManager();
    ????????
    if(layout?instanceof?FlowLayout)
    ????????
    return?((FlowLayout)figure.getLayoutManager()).isHorizontal();
    ????????
    if(layout?instanceof?ToolbarLayout)
    ????????????
    return?((ToolbarLayout)figure.getLayoutManager()).isHorizontal();
    ????????
    return?false;
    ????}
    }


    我們在getCreateCommand中返回了DbItemCreateCommand,將parent設(shè)為Table,child即為生成request攜帶的Column對象,因?yàn)镃olumn是沒有位置這個概念的,我們就不必把位置參數(shù)給它(給了也沒變量保存啊)它只可能是在這個表中的第幾個而已,并且,我們在上面也提到了,在移動ColumnFigure的時候 FlowLayoutEditPolicy可以繪制一條黑線,顯示當(dāng)前插入的位置,所以我們通過然后我們getInsertionReference方法得到當(dāng)前黑線所在索引所對應(yīng)的EditPart,然后得到該EditPart在TableEditPart的子EditPart中的位置,再傳遞給 Command,讓我們新生成的EditPart添加到該位置上。

    但是,要讓FlowLayoutEditPolicy顯示出黑線來,我們還需要復(fù)寫它的?isHorizontal方法,因?yàn)槟J(rèn)情況下,F(xiàn)lowLayoutEidtPolicy的? isHorizontal方法在運(yùn)行時,認(rèn)為安裝該EditPolicy的EditPart使用的是FlowLayout,但是我們這里用的是 ToolbarLayout,所以如果不復(fù)寫的話,將會拋出類型轉(zhuǎn)換的異常。

    我們只要簡單的進(jìn)行一下修改即可,或者直接讓他返回true得了 :)

    由于我們已經(jīng)在Column以及ColumnEditPart的基類中增加了添加子節(jié)點(diǎn)后的屬性更改代碼,所以這里就不用寫了。

    現(xiàn)在我們就可以通過點(diǎn)擊工具欄的column工具在Table中創(chuàng)建Column了。

    讓我們看看整體效果:





    6 . 結(jié)束語

    這次我們基本上解決了數(shù)據(jù)庫表以及數(shù)據(jù)庫字段的實(shí)現(xiàn)問題,下一章我們會接著往下講,其實(shí)代碼里面已經(jīng)有了,有興趣的朋友可以看看。

    下一章我會講一下如何去在GEF應(yīng)用中實(shí)現(xiàn)PropertyPage,以及Connection的一些問題


    評論

    # re: 數(shù)據(jù)庫字段的顯示以及增加  回復(fù)  更多評論   

    2007-01-11 09:43 by nomigd
    你好,我裝你的源代碼引入eclipse中,可是出現(xiàn)org.eclipse.core.internal.runtime.Assert類找不到,請問這個是什么類,在那個包中有。謝謝

    # re: 數(shù)據(jù)庫字段的顯示以及增加  回復(fù)  更多評論   

    2007-03-23 17:02 by amendar
    請問:我若想放一張圖片在編輯器中,這是如何實(shí)現(xiàn)的!!!
    QQ:31395591
    email:31395591@qq.com
    謝謝

    # re: 數(shù)據(jù)庫字段的顯示以及增加  回復(fù)  更多評論   

    2007-03-23 17:34 by Dart
    TO amendar:
    Figure是可以進(jìn)行繪制圖片的,使用graphics類的drawImage即可

    # re: 數(shù)據(jù)庫字段的顯示以及增加  回復(fù)  更多評論   

    2007-04-05 14:37 by 塵封
    我用GEF開發(fā)一個類似UML類圖編輯功能,現(xiàn)在所有的例子都是
    有一個Subject,subject有名字,可以增加子attribute,但是我還要為subject增加子opt,我現(xiàn)在面臨的問題是,如果opt和attribute同時作為subject的子,用兩個list在model中,只是在視圖中用lay區(qū)分它們的化,在subjectPart中g(shù)etchilden只能得到attribute的list或是opt的list,無法處理好它們,
    另一個解決的方法是用一個Cell作為subject的子,而且subject只含有2個Cell,并且作為subject創(chuàng)建的時候同時創(chuàng)建的,每個Cell各含有自己的子,分別處理attribute和opt,這樣可以各自控制自己的list,但是由于createFigure時,只能返回一個PART,這樣我的CellPart應(yīng)該如何創(chuàng)建出來呢

    謝謝,cliff4@21cn.com

    # re: 數(shù)據(jù)庫字段的顯示以及增加  回復(fù)  更多評論   

    2007-04-05 16:21 by Dart
    to 塵封:
    其實(shí)沒有必要再做兩個Cell出來,我也常遇到這種問題,我來說說我的解決辦法

    首先要認(rèn)定Subjuect維護(hù)了兩個List,一個是存放了opt,一個是存放了Attr.
    那可以將這兩個List看成是Subject的childrenModel,也就是說Subject只維護(hù)了兩個List而已,所以在Subject的EditPart中返回childrenModel的時候只需要將這兩個list放在一個List中返回.

    這樣一來,在GEF通過EditPartFactory查找模型對應(yīng)的Editpart時,就會出現(xiàn)兩個List的模型,這是沒有辦法分清的.
    我的做法是:使用EMF提供的List,因?yàn)檫@種list是可以攜帶其包含的元素的類型信息的;
    或者是自己寫一個List,讓它攜帶一些標(biāo)記信息來區(qū)分哪個是維護(hù)opt的,哪個是維護(hù)Attr的:

    public MyList extends ArrayList implements List{
    private Class elementClazz;

    public Class getElementClass(){};
    public void setElementClass(Class clazz){
    ..
    }
    }

    當(dāng)然,如果你使用的是JDK5.0的話,可以這么定義: ArrayList<elementClass>,這也可以取得元素類型.

    再就是在確保List中有數(shù)據(jù)的時候隨便其一個出來看看類型也行.

    這兩個List對應(yīng)的EditPart就很簡單了,就連figure也可以是簡單的透明Rectangle.

    上述方法雖然類似你的說的Cell的那種方案,但是你的模型就可以進(jìn)行少量的更改
    主站蜘蛛池模板: 1000部羞羞禁止免费观看视频| 搜日本一区二区三区免费高清视频| 中文字幕亚洲精品无码| 亚洲精品无码专区在线| 日本亚洲中午字幕乱码| 久草免费福利在线| 91精品国产免费| 好大好深好猛好爽视频免费| 免费人成在线观看播放国产 | 国产a不卡片精品免费观看| 久久国产成人亚洲精品影院 | 精品久久亚洲中文无码| 国产偷国产偷亚洲高清人| 99精品视频免费| 国产va免费精品观看精品| 国产成人3p视频免费观看 | 无码专区一va亚洲v专区在线| 亚洲精品成人片在线播放| 亚洲欧洲精品在线| 无套内谢孕妇毛片免费看看| 久久国产精品免费观看| 免费观看大片毛片| 国产成人A人亚洲精品无码| 亚洲 日韩 色 图网站| 国产免费一级高清淫曰本片| 无码区日韩特区永久免费系列| 免费v片在线观看无遮挡| 蜜芽亚洲av无码精品色午夜| 欧美日韩亚洲精品| 99热精品在线免费观看| 国产免费无遮挡精品视频| 亚洲第一福利视频| 鲁啊鲁在线视频免费播放| 91香焦国产线观看看免费| 免费jlzzjlzz在线播放视频| 亚洲激情电影在线| 亚洲一区二区三区免费| A级毛片内射免费视频| 日本亚洲成高清一区二区三区| 亚洲欧美成人一区二区三区| 久久国产免费观看精品|