如果你今天要在Eclipse plugin內顯示Graph node與node之間的視覺化圖形關聯的話,可以套
用Eclipse Zest Library來進行繪圖!
在這邊不是要說明怎麼使用Zest來建立節點間的關聯,而是要說明假設在不移入節點的情況
下,如何透過其他元件來觸發移入或點擊節點效果進而開啟提示訊息!
使用版本
Eclipse Zest version : 3.10.1 for Mars.1
用Eclipse Zest Library來進行繪圖!
在這邊不是要說明怎麼使用Zest來建立節點間的關聯,而是要說明假設在不移入節點的情況
下,如何透過其他元件來觸發移入或點擊節點效果進而開啟提示訊息!
使用版本
Eclipse Zest version : 3.10.1 for Mars.1
Eclipse version : Mars.2
一、安裝Eclipse Zest
請至網站下載GEF3-Update-3.10.1.zip
Eclipse → Help → Install New Software
將剛剛的zip檔載入進行安裝的動作
二、範例說明
首先,範例程式UI呈現在Eclipse view上,會分割畫面成左右兩部分。
左半邊為SWT List;右半邊為Zest Graph
請在plugin.xml內建立view extension
2.2、初始化元件
請見註解1 ~ 3部分
分別為分割視窗及建立List、Graph、GraphNode還有GraphConnection
特別注意的地方是
mainNode.setTooltip(new Label("......"));
這一段code針對該節點為另外指定Tooltip,若沒有另外指定的話預設是帶入節點名稱
2.3、定義事件處理
先說明List的事件定義
當我們點擊左半邊的List其中一個項目時
此時會先做node selection event的trigger,需在item內指定node,可透過graph.getNodes取得其
物件,目的是Graph是由其本身綁定事件,無法透過GraphNode來綁定,因此當指定item的
node時,回到graph selection事件處理可以由graph object setSelection來達到node被點擊的效
果! 這就如同您直接點擊node的行為是一樣的!
再過來是執行node MouseHover初始化的trigger
這邊會覺得奇怪,怎麼還需要做初始化的動作,直接做下一個MouseHover不就好了?!
原因在於
追到底層的code,查了一下發現要顯示tooltip時會呼叫displayToolTipNear,這邊會判斷
當下如果currentTipSource == hoverSource時則不進入條件,因此當您第一次點擊List的
main時可以正常進入,因為currentTipSource = null,但是當您連續第二次觸發main時,
此時currentTipSource 會等於 hoverSource,因此會無法正常trigger顯示tooltip!
當然,如果您是換點擊其他item,此時當然就會不等於,但是我們須預防會連續點擊!
因此,才想說使其currentTipSource被初始化,可以確認不等於hoverSource
PS. 也許這並不一定是唯一做法,僅供參考!!
那為啥正常去節點上直接hover後,再一次hover也可以正常顯示?
因為會有hover離開節點的事件處理,在這時就會初始化currentTipSource了!
也許這是處理MouseHover trigger不用作初始化的另一個解決方式吧?!
緊接著,為啥要設定event.x及event.y呢?
這邊也是追底層的code,發現graph內的tooltip到底哪一個要顯示。首先由root往下追蹤,再
來會掃到各節點及其擁有的Figure,由method去判斷findFigureAt(x, y)及containsPoint(x, y)是
否成立! 也就是判斷這個點是否涵蓋至Figure內! 如此一來就可以知道哪一個node的tooltip是否
要顯示!
三. 結果展示
一、安裝Eclipse Zest
請至網站下載GEF3-Update-3.10.1.zip
Eclipse → Help → Install New Software
將剛剛的zip檔載入進行安裝的動作
二、範例說明
首先,範例程式UI呈現在Eclipse view上,會分割畫面成左右兩部分。
左半邊為SWT List;右半邊為Zest Graph
程式碼如下
public class ZestGraphTest extends ViewPart{
org.eclipse.swt.widgets.List groupSets;
private int selectedIndex = -1;
@Override
public void createPartControl(Composite parent) {
// TODO Auto-generated method stub
String[] nodeName = {"main", "children1", "children2", "children3"};
//1. split Layout to two columns
Composite composite = new Composite(parent, SWT.NONE);
GridLayout gl = new GridLayout(2, false);
gl.marginHeight = 0;
gl.marginWidth = 0;
composite.setLayout(gl);
//2. create SWT List and set layout
groupSets = new org.eclipse.swt.widgets.List(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL);
GridData grid = new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1);
grid.widthHint = 200;
groupSets.setLayoutData(grid);
//3. create List, Graph, GraphNode, GraphConnection
GraphNode nodesList[] = new GraphNode[nodeName.length];
final Graph graph = new Graph(composite, SWT.BORDER);
GraphNode mainNode = null;
for(int i = 0 ; i < nodeName.length ; i++){
groupSets.add(nodeName[i]);
nodesList[i] = new GraphNode(graph, SWT.NONE, nodeName[i]);
if(i == 0){
mainNode = nodesList[i];
mainNode.setTooltip(new Label("Hello World!!\r\nHello World!!"));
}else{
new GraphConnection(graph, ZestStyles.CONNECTIONS_DIRECTED, mainNode, nodesList[i]);
}
}
graph.setLayoutAlgorithm(new RadialLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING), true);
GridData theGriddata = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
graph.setLayoutData(theGriddata);
//4. define graph selection event
graph.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
if(selectedIndex > -1){
Graph g = (Graph) e.getSource();
GraphItem sitem = (GraphItem) e.item;
GraphItem item[] = {sitem};
g.setSelection(item);
}
}
});
//5. define List selection event
groupSets.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
selectedIndex = groupSets.getSelectionIndex();
Event event = new Event();
@SuppressWarnings("unchecked")
List nodeLists = graph.getNodes();
GraphNode node = nodeLists.get(selectedIndex);
//node selected by trigger
event.widget = graph;
event.item = node;
graph.notifyListeners(SWT.Selection, event);
//node MouseHover initialize by trigger
event.x = 0;
event.y = 0;
graph.notifyListeners(SWT.MouseHover, event);
//node MouseHover to show tooltip by trigger
event.x = node.getLocation().x;
event.y = node.getLocation().y;
graph.notifyListeners(SWT.MouseHover, event);
selectedIndex = -1;
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
2.1、繼承ViewPart請在plugin.xml內建立view extension
2.2、初始化元件
請見註解1 ~ 3部分
分別為分割視窗及建立List、Graph、GraphNode還有GraphConnection
特別注意的地方是
mainNode.setTooltip(new Label("......"));
這一段code針對該節點為另外指定Tooltip,若沒有另外指定的話預設是帶入節點名稱
2.3、定義事件處理
先說明List的事件定義
當我們點擊左半邊的List其中一個項目時
此時會先做node selection event的trigger,需在item內指定node,可透過graph.getNodes取得其
物件,目的是Graph是由其本身綁定事件,無法透過GraphNode來綁定,因此當指定item的
node時,回到graph selection事件處理可以由graph object setSelection來達到node被點擊的效
果! 這就如同您直接點擊node的行為是一樣的!
再過來是執行node MouseHover初始化的trigger
這邊會覺得奇怪,怎麼還需要做初始化的動作,直接做下一個MouseHover不就好了?!
原因在於
追到底層的code,查了一下發現要顯示tooltip時會呼叫displayToolTipNear,這邊會判斷
當下如果currentTipSource == hoverSource時則不進入條件,因此當您第一次點擊List的
main時可以正常進入,因為currentTipSource = null,但是當您連續第二次觸發main時,
此時currentTipSource 會等於 hoverSource,因此會無法正常trigger顯示tooltip!
當然,如果您是換點擊其他item,此時當然就會不等於,但是我們須預防會連續點擊!
因此,才想說使其currentTipSource被初始化,可以確認不等於hoverSource
PS. 也許這並不一定是唯一做法,僅供參考!!
那為啥正常去節點上直接hover後,再一次hover也可以正常顯示?
因為會有hover離開節點的事件處理,在這時就會初始化currentTipSource了!
也許這是處理MouseHover trigger不用作初始化的另一個解決方式吧?!
緊接著,為啥要設定event.x及event.y呢?
這邊也是追底層的code,發現graph內的tooltip到底哪一個要顯示。首先由root往下追蹤,再
來會掃到各節點及其擁有的Figure,由method去判斷findFigureAt(x, y)及containsPoint(x, y)是
否成立! 也就是判斷這個點是否涵蓋至Figure內! 如此一來就可以知道哪一個node的tooltip是否
要顯示!
三. 結果展示
留言
張貼留言