SWT/JFACE 在Tableviewer中只在表頭上右擊顯示上下文菜單

通常,如果不做特殊處理的話,在表頭(樹頭,以下統稱表頭)的上點擊右鍵和在表體裏點擊右鍵,顯示的菜單結果一樣的。

 

有時候我希望能顯示不一樣的菜單,例如在Windows的Explorer上,如果在表頭點擊菜單,顯示就是可顯示的列項。


在SWT中,缺省是不支持對錶頭添加菜單的,不過我們可以自己實現這個功能。

 

在SWT中有一個MenuDetect事件,可以查看源碼,在Widget類的showMenu(int x, int y):

boolean showMenu (int x, int y) {
	Event event = new Event ();
	event.x = x;
	event.y = y;
	sendEvent (SWT.MenuDetect, event);
	// widget could be disposed at this point
	if (isDisposed ()) return false;
	if (!event.doit) return true;
	Menu menu = getMenu ();
	if (menu != null && !menu.isDisposed ()) {
		if (x != event.x || y != event.y) {
			menu.setLocation (event.x, event.y);
		}
		menu.setVisible (true);
		return true;
	}
	return false;
}

 可以看到,每次菜單顯示之前,會先發出一個SWT.MenuDetect事件,之後纔是顯示具體的Menu。所以如果我們想對錶頭和表體顯示不同的菜單,可以在每次顯示菜單前,根據點擊位置的不同,設置不同的菜單,最後讓它顯示出來。

 

根據以上源碼,顯然,我們可以增加一個SWT.MenuDetect事件監聽,來設置菜單,這個菜單在之後就會被顯示出來。

 

看以下代碼:

		final Menu bodyMenu = ...;
                final Menu headerMenu = ... ;
		table.addListener(SWT.MenuDetect, new Listener() {
			public void handleEvent(Event event) {
				Table t = (Table) event.widget;
				Point pt = t.getDisplay().map(null, t, event.x, event.y);
				Rectangle clientArea = t.getClientArea();
				boolean isHeader = ((pt.y - clientArea.y) <= t
						.getHeaderHeight());
				t.setMenu(isHeader ? headerMenu : bodynMenu);
			}
		});

每次,當Menu顯示之前,我們把event中的x,y,映射到表中的具體位置,然後用表頭的高度與它的大小關係,來判斷當前點擊處是否在表頭處,如果在表頭處,則顯示錶頭菜單,否則顯示錶體菜單。

 

這裏都假設表頭是可見的,如果表頭不可見。這篇文章就沒意義了。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章