【原创】关于JFace的一个bug(可编辑单元格双击,会频繁调用TableViewer的双击处理)

【原创】关于JFace的一个bug(可编辑单元格双击,会频繁调用TableViewer的双击处理)

        闲话稍说,直接上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);
                            }
                        }
                    };
                }
            }

        

         希望能帮到遇到类似问题的同学

本博客中的所有文章、随笔除了标题中含有引用或者转载字样的,其他均为原创。转载请注明出处,谢谢!

你可能感兴趣的:(【原创】关于JFace的一个bug(可编辑单元格双击,会频繁调用TableViewer的双击处理))