SWT/JFACE 在Tableviewer中只在表头上右击显示上下文菜单

来源:互联网 发布:螺纹钢的算法 编辑:程序博客网 时间:2024/06/07 07:14

通常,如果不做特殊处理的话,在表头(树头,以下统称表头)的上点击右键和在表体里点击右键,显示的菜单结果一样的。

 

有时候我希望能显示不一样的菜单,例如在Windows的Explorer上,如果在表头点击菜单,显示就是可显示的列项。


在SWT中,缺省是不支持对表头添加菜单的,不过我们可以自己实现这个功能。

 

在SWT中有一个MenuDetect事件,可以查看源码,在Widget类的showMenu(int x, int y):

[java] view plaincopy
  1. boolean showMenu (int x, int y) {  
  2.     Event event = new Event ();  
  3.     event.x = x;  
  4.     event.y = y;  
  5.     sendEvent (SWT.MenuDetect, event);  
  6.     // widget could be disposed at this point  
  7.     if (isDisposed ()) return false;  
  8.     if (!event.doit) return true;  
  9.     Menu menu = getMenu ();  
  10.     if (menu != null && !menu.isDisposed ()) {  
  11.         if (x != event.x || y != event.y) {  
  12.             menu.setLocation (event.x, event.y);  
  13.         }  
  14.         menu.setVisible (true);  
  15.         return true;  
  16.     }  
  17.     return false;  
  18. }  

 可以看到,每次菜单显示之前,会先发出一个SWT.MenuDetect事件,之后才是显示具体的Menu。所以如果我们想对表头和表体显示不同的菜单,可以在每次显示菜单前,根据点击位置的不同,设置不同的菜单,最后让它显示出来。

 

根据以上源码,显然,我们可以增加一个SWT.MenuDetect事件监听,来设置菜单,这个菜单在之后就会被显示出来。

 

看以下代码:

[java] view plaincopy
  1. final Menu bodyMenu = ...;  
  2.               final Menu headerMenu = ... ;  
  3. table.addListener(SWT.MenuDetect, new Listener() {  
  4.     public void handleEvent(Event event) {  
  5.         Table t = (Table) event.widget;  
  6.         Point pt = t.getDisplay().map(null, t, event.x, event.y);  
  7.         Rectangle clientArea = t.getClientArea();  
  8.         boolean isHeader = ((pt.y - clientArea.y) <= t  
  9.                 .getHeaderHeight());  
  10.         t.setMenu(isHeader ? headerMenu : bodynMenu);  
  11.     }  
  12. });  

每次,当Menu显示之前,我们把event中的x,y,映射到表中的具体位置,然后用表头的高度与它的大小关系,来判断当前点击处是否在表头处,如果在表头处,则显示表头菜单,否则显示表体菜单。

 

这里都假设表头是可见的,如果表头不可见。这篇文章就没意义了。

0 0
原创粉丝点击