GEF中自带有Directeditrequest,所以实现Directedit还是比较容易的,八进制的gef例子里面就有实现.但我在给directedit加上content assist的时候却发现由一个小bug不太好弄,费了两天才搞定,现在先记下来,以供参考
directedit是通过一个text celleditor来实现编辑功能的,所以可以在directeditmanager类里面的initCellEditor方法里面加上ContentAssistHandler来实现auto complete.但是加上去之后却发现有一个问题:不支持用鼠标来选择proposal.只能用键盘上的上下箭头来选择.虽然也可以用,但是终究不是那么的人性化.
为了修复这个bug,走了不少的弯路,一开始以为是contentassist的问题,因为它是deprecated,所以换了3.3里面的assist api,发现还是不行.后来才知道是因为celleditor有一个focus listener,当用户点击proposals 来选择一行的时候,celleditor的focus就lost了,就会调用focusLost方法,导致directedit编辑失败.所以我重写了celleditor的focusLost方法,把它设成当focus在contentassist的popup dialog就什么都不干,否则调用父类的focusLost方法.理论上是一个好的解决方法,但是contentassist的hasPopupFocus居然一直都返回false,这个方法也失败了.
最后,在bug.eclipse.org上面有人提到GMF里面的TextDirectEditManager是可以做到用鼠标选择proposal的,于是又去看gmf的这个类,它也是继承自DirectEditManager,不过它消除这个bug不是在listener上作文章,而是在commit方法里面,在这个方法里面判断popup dialog是否是active的,如果是的话则给celleditor加上deactive lock,不允许它deactive,这样来实现用鼠标选择proposal.
下面是TextDirectEditManager的方法commit里面的部分代码:
Shell activeShell = Display.getCurrent().getActiveShell();
if (activeShell != null
&& getCellEditor().getControl().getShell().equals(
activeShell.getParent())) {
Control[] children = activeShell.getChildren();
if (children.length == 1 && children[0] instanceof Table) {
/*
* CONTENT ASSIST: focus is lost to the content assist pop up -
* stay in focus
*/
getCellEditor().getControl().setVisible(true);
((MyTextCellEditor) getCellEditor()).setDeactivationLock(true);
return;
}
}
下面是MyTextCellEditor里面对于deactive lock的应用,MyTextCellEditor的deactive之前会判断一下deactive lock是否为true:
public boolean isDeactivationLocked() {
return deactivationLock;
}
public void deactivate() {
if (! isDeactivationLocked())
super.deactivate();
setDeactivationLock(false);
}
public void setDeactivationLock(boolean deactivationLock) {
this.deactivationLock = deactivationLock;
}