BaNg

Just Do It!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  33 Posts :: -1 Stories :: 178 Comments :: 0 Trackbacks
GEF中大部分action对位置不敏感,但还是有例外,典型的如paste,context menu中的某个action需要将clipboard中的东西paste到右键单击位置。如下图:


即使在GMF中, DiagramAction也是取得是鼠标点击paste时的位置,而不是之前右键单击出现contxt menu的位置。这里“定点”关键是在选择paste之前右键单击的位置已经被记住了,并且对context menu中所有对位置敏感的action都有效,比如merge, duplicate等。

下面分三步完成:

1 定义一个接口,为所有位置敏感action提供位置信息

public interface ILocationWare {
    
void setLocation(int x,int y);
}

2 注册一个listener到GEF editor的context menu,提供位置记忆,这个是关键。

public class LivingContextMenu extends ContextMenuProvider {

    
private LivingEditor editor;
    
private IMenuListener listener = new IMenuListener(){

        @Override
        
public void menuAboutToShow(IMenuManager manager) {
            Control canvas 
= getViewer().getControl();
            Point cursor_location 
= canvas.getDisplay().getCursorLocation();
            Point relative_canvas 
= canvas.toControl(cursor_location);
            setItemLocation(manager,relative_canvas);
        }

        
private void setItemLocation(IMenuManager manager, Point relative_canvas) {
            IContributionItem[] items 
= manager.getItems();
            
for (int i =0; i < items.length; i++)
            {
                IContributionItem item 
= items[i];
                
if (item instanceof ActionContributionItem)
                {
                    IAction host_action 
= ((ActionContributionItem)item).getAction();
                    
if (host_action instanceof ILocationWare)
                        ((ILocationWare)host_action).setLocation(relative_canvas.x, relative_canvas.y);
                    
                }
                
else if (item instanceof IMenuManager)
                {
                    setItemLocation((IMenuManager)item, relative_canvas);
                }
            }
        }
        
    };
    
public LivingContextMenu(LivingEditor lv) {
        
super((GraphicalViewer)lv.getAdapter(GraphicalViewer.class));
        editor 
= lv;
        addMenuListener(listener);
    }
    .
        .
        .
    @Override
    
public void dispose() {
        removeMenuListener(listener);
        
super.dispose();
    }

}
原理就是右键单击后,context menu的listener已经记住了鼠标在graphicalviewer control(一般为FigureCanvas)右击位置,并告知给所有context menu中对位置敏感的action。

3 对位置敏感的action实现ILocationWare接口,比如paste。

public class PasteAction extends SelectionAction implements ILocationWare {
    
    
private Point location = new Point(10,10);
    
private boolean contextTrigged=false;
    
public PasteAction(LivingEditor part) {
        
super(part);
    }

    @Override
    
public void run() {
      
//some operations depend on location
    }
    
    @Override
    
public void setLocation(int x, int y) {
        location.setLocation(x, y);
        contextTrigged 
= true;
    }
    @Override
    
protected void init() {
        
super.init();
        setId(ActionFactory.PASTE.getId());
        ISharedImages workbench_images 
= PlatformUI.getWorkbench().getSharedImages();
        setImageDescriptor(workbench_images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
        setDisabledImageDescriptor(workbench_images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
    }
}

这种解决同样适用于GMF的DiagramAction。(DiagramAction也是Action的子类)



posted on 2008-08-20 22:26 Always BaNg. 阅读(993) 评论(0)  编辑  收藏 所属分类: JavaEclipse

标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-08-20 22:32 编辑过