在GEF中實(shí)現(xiàn)帶content assist的Directedit
GEF中自帶有Directeditrequest,所以實(shí)現(xiàn)Directedit還是比較容易的,八進(jìn)制的gef例子里面就有實(shí)現(xiàn).但我在給directedit加上content assist的時候卻發(fā)現(xiàn)由一個小bug不太好弄,費(fèi)了兩天才搞定,現(xiàn)在先記下來,以供參考
directedit是通過一個text celleditor來實(shí)現(xiàn)編輯功能的,所以可以在directeditmanager類里面的initCellEditor方法里面加上ContentAssistHandler來實(shí)現(xiàn)auto complete.但是加上去之后卻發(fā)現(xiàn)有一個問題:不支持用鼠標(biāo)來選擇proposal.只能用鍵盤上的上下箭頭來選擇.雖然也可以用,但是終究不是那么的人性化.
為了修復(fù)這個bug,走了不少的彎路,一開始以為是contentassist的問題,因為它是deprecated,所以換了3.3里面的assist api,發(fā)現(xiàn)還是不行.后來才知道是因為celleditor有一個focus listener,當(dāng)用戶點(diǎn)擊proposals 來選擇一行的時候,celleditor的focus就lost了,就會調(diào)用focusLost方法,導(dǎo)致directedit編輯失敗.所以我重寫了celleditor的focusLost方法,把它設(shè)成當(dāng)focus在contentassist的popup dialog就什么都不干,否則調(diào)用父類的focusLost方法.理論上是一個好的解決方法,但是contentassist的hasPopupFocus居然一直都返回false,這個方法也失敗了.
最后,在bug.eclipse.org上面有人提到GMF里面的TextDirectEditManager是可以做到用鼠標(biāo)選擇proposal的,于是又去看gmf的這個類,它也是繼承自DirectEditManager,不過它消除這個bug不是在listener上作文章,而是在commit方法里面,在這個方法里面判斷popup dialog是否是active的,如果是的話則給celleditor加上deactive lock,不允許它deactive,這樣來實(shí)現(xiàn)用鼠標(biāo)選擇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;
}
}
public boolean isDeactivationLocked() {
return deactivationLock;
}
public void deactivate() {
if (! isDeactivationLocked())
super.deactivate();
setDeactivationLock(false);
}
public void setDeactivationLock(boolean deactivationLock) {
this.deactivationLock = deactivationLock;
}