在gef項(xiàng)目中連線一直扮演這個(gè)不可或缺的角色。碰巧前段時(shí)間有個(gè)機(jī)會(huì)好好的看了這個(gè)部分的內(nèi)容。下面就把我的一點(diǎn)點(diǎn)認(rèn)識(shí)和大家分享。
首先要在模型上支持,能夠保存連接的信息。對(duì)于不同的項(xiàng)目有不同的要求。我們通過兩個(gè)例子就可以看出這一點(diǎn)來。
1、http://www13.plala.or.jp/observe/GEF/示例中的GEF6.zip (下面稱這個(gè)例子為HelloWold)
運(yùn)行的結(jié)果入下圖所示:
它的模型可以使用如下的類圖來表示:
用來描述Connection的分別是LineConnectionModel和ArrowConnectionModel這兩個(gè)類。這兩個(gè)類的父類和圖形模型(HellowModel)相關(guān)。
2、IBM紅皮書中的GEF范例(下面稱這個(gè)例子為workflow)
運(yùn)行效果如下圖:
他的模型可用下面的類圖描述:
其實(shí)連接的模型應(yīng)該很簡單,他只要能保存他的兩端的對(duì)象就好了。圖形模型(如HelloWold中的HelloModel)能夠保持與他相關(guān)連的連接(HelloWold中的LineConnectionModel或ArrowConnectionModel)。
看完了Model,我們下面就可以看看EditPart部分了。
要看EditPart當(dāng)然是要看最關(guān)鍵的了。也就是和連接直接關(guān)聯(lián)的EditPart了。分別察看了和連接相關(guān)的EditPart,發(fā)現(xiàn)他們都會(huì)實(shí)現(xiàn)一個(gè)叫org.eclipse.gef.NodeEditPart的接口。如下圖所示:

在nodeEditPart中有四個(gè)方法需要實(shí)現(xiàn)。通過這個(gè)四個(gè)方法的名字就可以看出他們和Anchor2密切相關(guān)。下面就來看看這幾個(gè)方法的具體功能:
ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection);
當(dāng)需要畫連接的時(shí)候,通過這個(gè)方法獲取連接的源錨點(diǎn)。不管這個(gè)錨點(diǎn)在什么位置,他取得以后直接就用它作為源點(diǎn)了。
ConnectionAnchor getSourceConnectionAnchor(Request request);
當(dāng)在準(zhǔn)備創(chuàng)建連接的時(shí)候,通過Request來獲取新連接的源錨點(diǎn)。
另外的兩個(gè)就不再啰嗦了。是為了獲得目標(biāo)的錨點(diǎn)。
但是我們肯定看到了HelloWold和Workflow中的連接有點(diǎn)不一樣。HelloWold中直接是圖元上的,而workflow是通過連接基本圖元上面的一個(gè)子圖元而連接的。簡單來說就是他們連接的anchor有點(diǎn)不一樣,這樣就會(huì)出現(xiàn)執(zhí)行結(jié)果的不同。
下面來看看他們到底是怎么實(shí)現(xiàn)的。根據(jù)上面提到的。錨點(diǎn)的獲取是通過getSourceConnectionAnchor和getTargetConnectionAnchor方法來獲取的。我們只需要好好比對(duì)一下他們這幾個(gè)方法的不同就可以了。
HelloWold中的getSourceConnectionAnchor
public ConnectionAnchor getSourceConnectionAnchor(Request request) {
returnnew ChopboxAnchor(getFigure());
}
這里就簡單的創(chuàng)建一個(gè) ChopboxAnchor 就好了。這個(gè)就可以直接連到該Figure上了。
在workflow中這個(gè)情況稍微有一點(diǎn)復(fù)雜了。先不說,還是看看他的 getSourceConnectionAnchor 是怎么實(shí)現(xiàn)的。
public ConnectionAnchor getSourceConnectionAnchor(
ConnectionEditPart connection) {
Connection edge = (Connection) connection.getModel();
return getNodeFigure().getConnectionAnchor(edge.getSource().getName());
}
/**
*returnsananchorgivenitsname
*
*@paramportNamenameoftheanchor
*@returntheanchorwiththename<code>portName</code>
*/
public ConnectionAnchor getConnectionAnchor(String portName) {
return (ConnectionAnchor)connectionAnchors.get( portName );
}
protected Hashtable connectionAnchors = new Hashtable(7);
/**
*Addaninputportanditsanchor
*
*@paramportName
*uniquenametorefertotheport
*/
publicvoid addInput(String portName) {
InputPortFigure inputPort = new InputPortFigure();
add(inputPort);
PortConnectionAnchor anchor = new PortConnectionAnchor(inputPort);
getTargetConnectionAnchors().add(anchor);
connectionAnchors.put(portName, anchor);
}
通過這幾個(gè)方法可以看出它是在添加Input時(shí)候就創(chuàng)建好了一個(gè)和PortFigure 相關(guān)Anchor并把它保存起來。在要用的時(shí)候就把它取出來。這樣就搞定了。
具體的可以參考這兩個(gè)例子的代碼。好了,打完收工。
參考文檔
IBM 紅皮書