闲话稍说,直接上bug视频:
Bug视频
大致现象:在一个可编辑tableviewer的单元格中,双击,对应的编辑对话框会不时弹出多次。我这边严重的时候,会连续弹出将近20次,那就只能修改了~_~
Bug分析:
调试了一把,发现是SWT底层将同一鼠标事件(通过event.time可以确认)连续发送了多次。而JFace中的TableEditorImpl将这事件转发给了tableviewer,tableviewer会进一步调用对应的double click listener。开发人员做的double click listener实现就是弹出一个编辑对话框。问题就出现了,当弹出的对话框关闭之后,马上有弹出了,上面说过,重复事件又被广播了~_~
修改方法:
时间较紧,就直接在TableEditorImpl这边修改了一把。将org.eclipse.jface插件以源码工程方式导入,将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、在转发双击事件之前,做时间戳检查,避免同一双击事件被处理了多次
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();
//检查本次要处理的双击事件是否和上次的事件重复
if (e.time != lastDoubleclickEventTime) {
lastDoubleclickEventTime = e.time;
handleDoubleClickEvent();
}
} else if (mouseListener != null) {
control.removeMouseListener(mouseListener);
}
}
};
}
}
希望能帮到遇到类似问题的同学
本博客中的所有文章、随笔除了标题中含有引用或者转载字样的,其他均为原创。转载请注明出处,谢谢!