【原創(chuàng)】關(guān)于JFace的一個bug(可編輯單元格雙擊,會頻繁調(diào)用TableViewer的雙擊處理)
閑話稍說,直接上bug視頻:
Bug視頻
大致現(xiàn)象:在一個可編輯tableviewer的單元格中,雙擊,對應(yīng)的編輯對話框會不時彈出多次。我這邊嚴(yán)重的時候,會連續(xù)彈出將近20次,那就只能修改了~_~
Bug分析:
調(diào)試了一把,發(fā)現(xiàn)是SWT底層將同一鼠標(biāo)事件(通過event.time可以確認(rèn))連續(xù)發(fā)送了多次。而JFace中的TableEditorImpl將這事件轉(zhuǎn)發(fā)給了tableviewer,tableviewer會進(jìn)一步調(diào)用對應(yīng)的double click listener。開發(fā)人員做的double click listener實現(xiàn)就是彈出一個編輯對話框。問題就出現(xiàn)了,當(dāng)彈出的對話框關(guān)閉之后,馬上有彈出了,上面說過,重復(fù)事件又被廣播了~_~
修改方法:
時間較緊,就直接在TableEditorImpl這邊修改了一把。將org.eclipse.jface插件以源碼工程方式導(dǎo)入,將TableEditorImpl.java類做了一定的修改,加了一個雙擊事件的時間戳判斷。
【TableEditorImpl.java原有代碼,Eclipse 3.2版本】
mouseListener = new MouseAdapter() {
public void mouseDown(MouseEvent e) {
// time wrap?
// check for expiration of doubleClickTime
if (e.time <= doubleClickExpirationTime) {
control.removeMouseListener(mouseListener);
cancelEditing();
handleDoubleClickEvent();
} else if (mouseListener != null) {
control.removeMouseListener(mouseListener);
}
}
};
【修改后代碼】
1、首先在TableEditorImpl中定義了一個雙擊事件的時間戳,緩存上次處理的雙擊事件的時間戳
2、在轉(zhuǎn)發(fā)雙擊事件之前,做時間戳檢查,避免同一雙擊事件被處理了多次
abstract class TableEditorImpl {
...其他代碼省略
//add by zhuxing:上次處理的雙擊事件的時間戳
private int lastDoubleclickEventTime;
private void activateCellEditor() {
..................................
mouseListener = new MouseAdapter() {
public void mouseDown(MouseEvent e) {
// time wrap?
// check for expiration of doubleClickTime
if (e.time <= doubleClickExpirationTime) {
control.removeMouseListener(mouseListener);
cancelEditing();
//檢查本次要處理的雙擊事件是否和上次的事件重復(fù)
if (e.time != lastDoubleclickEventTime) {
lastDoubleclickEventTime = e.time;
handleDoubleClickEvent();
}
} else if (mouseListener != null) {
control.removeMouseListener(mouseListener);
}
}
};
}
}
希望能幫到遇到類似問題的同學(xué)
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請注明出處,謝謝!