簡介:本文是gef高階的第四部分,主要描述了locator的概念和使用方法。locator是 乙個圖形定位器,用來動態的決定某個圖形相對於另外乙個圖形的位置,因此可以用來構造一些 複雜的圖形或者實現一些比較有趣的功能。由於eclipse 3.3已經發布,本文的示例**是在 eclipse 3.3, gef 3.3執行除錯的。
本文是gef高階的第四部分,主要描述了locator的概念和使用方法。locator是乙個圖形定 位器,用來動態的決定某個圖形相對於另外乙個圖形的位置,因此可以用來構造一些複雜的圖形或者 實現一些比較有趣的功能。由於eclipse 3.3已經發布,本文的示例**是在eclipse 3.3, gef 3.3 執行除錯的。
locator
locator,顧名思義,是乙個定位器。我們先來看看這個介面:
public inte***ce locator
這個介面非常簡單,只有乙個方法,引數是乙個ifigure,所以首先可以明確的是:locator是乙個 圖形定位器。那麼乙個locator用在什麼地方,又為什麼要用locator呢?一般來講,如果你希望乙個圖形 能跟著另外乙個圖形移動,那麼locator就很有用了。因此locator是相對定位的有利工具。我們下面來介 紹locator的幾個典型應用。
connection label
我們在執行gef shapes的例子時,可以看到圖形之間可以有連線,但是連線上沒有文字說明,如果有 文字說明的話,會有如下圖所示的效果:
看到連線上有了乙個「label」的字樣,你可以把它叫做connection label(連線標籤)。總之, 這個標籤是附著在連線上的。不光如此,如果你拖動連線,這個標籤也會跟著移動,這就是locator 的功勞。我們先來修改shapes例子的**,給連線加上這樣的標籤。要修改的地方在connectioneditpart 的createfigure方法裡,修改後如下所示:
清單2. 為連線加上label
protected ifigure createfigure()
加這麼乙個label確實很簡單,我們先建立乙個label物件,再將它加到連線裡面,所以本質上label是連線的 乙個孩子。在新增的時候,我們使用了midpointlocator, 這是gef預設帶的乙個locator,作用是把圖形定位 到連線的中點。所以我們看到label的中點始終和連線的中點相同。而連線的中點又叫做midpointlocator的 reference point(參考點), 我們在本系列的第一部分裡面介紹過anchor(錨點),這個參考點的概念與其是類似的。
隨之而來我們會發現乙個侷限性:這個label永遠只能在連線的中心,無法移動到其它的地方。在有些時候這 確實是個問題:比如某個圖特別複雜,連線特別多,以致於連線上的標籤都重疊在了一起,可是由於它不能拖動,所 以看上去很不美觀。如果我們希望這個label能被拖動該怎麼辦呢?有兩個方案:
為這個label建立乙個editpart,負責控制這個label的移動,改變大小,等等。
使用乙個自定義的locator,並處理label的滑鼠事件,隨時重新整理它的位置
第一種方法需要的**稍多且不符合本文主題。我們來看看第二種方法該如何實施。
確定locator的策略
首要的問題是我們的locator如何工作呢?我們已經使用了midpointlocator,它可以隨時定位到連線的中點, 如果我們給它加乙個偏移,不就可以實現拖動到任何位置的功能了嗎?這個概念如圖2所示:
策略定下來之後我們來實現乙個midpointoffsetlocator,它直接繼承自midpointlocator,但是我們給它添 加乙個offset的成員變數,這樣我們就可以控制標籤中點的位置了。**如下所示:
清單3. midpointoffsetlocator的實現
public class midpointoffsetlocator extends midpointlocator
@override
protected point getreferencepoint()
public point getoffset()
public void setoffset(point offset)
}
關鍵的方法在於我們覆蓋了getreferencepoint(),讓它返回之前加上我們的偏移量。就這麼簡單,我們自己的locator誕生了!
處理滑鼠事件
locator有了,下面的問題就是如何才能在適當的時機修改這個偏移量呢?第一想到的就是滑鼠事件***。由於figure本身 已經支援新增各種各樣的***,所以這一步也非常簡單。我們繼續修改connectioneditpart的createfigure方法,給我們的label 加上滑鼠事件處理方法,如下所示:
清單4. 新增滑鼠事件***
protected ifigure createfigure()
public void mousepressed(mouseevent me)
public void mousereleased(mouseevent me)
});label.addmousemotionlistener(new mousemotionlistener()
me.consume();
}// 省略其它無關**
......
});return connection;
}
要注意的有三點,第一我把midpointlocator替換成了我們自己的locator,第二我在connectioneditpart加了四個成員變數(dx, dy, anchorx, anchory)來跟蹤滑鼠位置,第三我在滑鼠拖動事件中修改偏移量並重新整理它,但是為了安全起見,我先判斷了constraint型別。
小節總結
我們現在完成了label的拖動功能,不過你可以發現一些可以繼續提高的地方,最明顯的莫過於label的位置不能儲存。我們應該把這個偏移量儲存到connection模型中去。這個問題和本文無關,留給讀者做個練習。本小節的示例**在org.eclipse.gef.examples.shapes_locator_step1.zip中,大家可以看看實際的效果。
handle
locator另乙個典型的應用是用在handle中,所謂handle,就是你選擇乙個圖形之後,在它的邊框周圍出現的一些輔助性的圖形,比如一些小方塊。如下圖所示:
因為handle也使用了locator,所以我們在拖**形的時候,handle的位置也會隨之更新。回頭看看上一小節中的label,可以發現乙個美中不足的是:label的周圍沒有handle,這樣的話使用者可能會不知道我們的label是可以拖動的,對使用者不太直觀,如果能在連線被選擇的時候把label的周圍也加上handle,那麼使用者可以容易的發現這個label原來也支援拖動,這有利於提高使用者友好度。本小節的例子就來實現這個功能。
myconnectionendpointeditpolicy
追究handle的發源地,會發現連線上的handle是在connectionendpointeditpolicy中建立的, 我們要新增handle,自然就是要實現乙個自己的editpolicy了。關於editpolicy的相關概念,這裡不做贅述。觀察connectionendpointeditpolicy的實現,可以看到乙個有趣的方法createselectionhandles,那麼我們來覆蓋它,如下:
清單5. 為label新增handle
public class myconnectionendpointeditpolicy extends connectionendpointeditpolicy
return handles;}}
我們遍歷了連線的所有孩子,如果它是乙個label,就為它建立乙個movehandle,movehandle使用了movehandlelocator,這些類都是gef自帶的,不需要費什麼功夫。
有了自定義的editpolicy,別忘了在connectioneditpart中替換原來的editpolicy,這部分**過於簡單,省略不提。
修改label上的滑鼠事件處理**
到這裡為止,我們的label就有了handle了,如下圖所示:
小節總結
回頁首
結束語gef中的幾乎一切東西都可以定製,本文介紹的是locator的定製,locator是相對布局的關鍵介面。靈活使用locator,可以實現一些很有趣的功能。
第四部分 方法3
對employee.calculatepay方法的呼叫是問題的原因。我們需要的是晚繫結。晚繫結 latebinging 意味著編譯器到執行時才選擇要執行的方法。為了迫使編譯器呼叫向上型別轉換得到的物件的方法的正確版本。我們使用了兩個關鍵字 virtual 和override.必須在基類方法中使用vi...
第四部分 方法5
linux繼承了unix作業系統結構清晰的特點。在linux下的檔案結構非常有條理。但是,上述的優點只有在對linux相當熟悉時,才能體會到。vmlinuz 我們已經知道,每乙個linux都有乙個核心 vmlinuz 我們在這個核心上新增上可以完成各種特定功能的模組,每個模組就體現在 linux中各...
JavaScript筆記(第四部分)
命 名 空 間 管理變數,防止汙染全域性,適用於模組開發 之 前 的 解 決 辦 方 已經不用 命名空間 var org xuming department2 lisi 了解即可 用 法 org.department1.jicheng.name 簡化 var jc org.department1.j...