CheckboxTreeviewer选中状态问题

来源:互联网 发布:守望先锋网络质量显示 编辑:程序博客网 时间:2024/05/19 01:58

在使用JFace的CheckboxTreeViewer做开发时,如果遇到如下问题:

  • check状态点击出现问题,check A却让B的状态check了
  • 置灰(setGrayed)某个元素,元素状态并没有置灰,而改成了checked
  • 选中某个元素,在selection linstener中监听到的选中元素却不是选中的元素
  • 。。。。

如果遇到上述一系列问题(或者其他比较反常的问题),那很有可能你的问题原因是:CheckboxTreeViewer的某一级树结构中含有重复元素。举例说明:
假如CheckboxTreeViewer的input为如下结构:
A
|__B //1
C
|__B //2
在选中 2 的时候,可能变化的是1的状态,或者出现其他异常问题。该问题出现根本原因是AbstractTreeViewer(CheckboxTreeViewer的父类)的一个Bug,有如下代码:

protected boolean isSameSelection(List items, Item[] current) {        // If they are not the same size then they are not equivalent        int n = items.size();        if (n != current.length) {            return false;        }        CustomHashtable itemSet = newHashtable(n * 2 + 1);        for (Iterator i = items.iterator(); i.hasNext();) {            Item item = (Item) i.next();            Object element = item.getData();            itemSet.put(element, element);        }        // Go through the items of the current collection        // If there is a mismatch return false        for (int i = 0; i < current.length; i++) {            if (current[i].getData() == null                    || !itemSet.containsKey(current[i].getData())) {                return false;            }        }        return true;    }

这段代码用来比较树上的元素是否相等,在比较时,只考虑本级目录,而未考虑父目录是否相同,一种改进方案是(摘抄自stackoverflow):

 protected boolean isSameSelection(List items, Item[] current) {                // If they are not the same size then they are not equivalent                int n = items.size();                if (n != current.length) {                    return false;                }                Set itemSet = new HashSet(n * 2 + 1);                for (Iterator i = items.iterator(); i.hasNext();) {                    Item item = (Item) i.next();                    itemSet.add(getTreePathFromItem(item));                }                // Go through the items of the current collection                // If there is a mismatch return false                for (int i = 0; i < current.length; i++) {                    if (current[i].getData() == null                            || !itemSet.contains(getTreePathFromItem(current[i]))) {                        return false;                    }                }                return true;            }

在改进的代码中,将 对数据的判断改为了对路径的判断,用于解决元素重复这个问题。

参考资料:http://stackoverflow.com/questions/6289049/treeviewer-setselection-does-not-select-the-correct-item-after-the-path-given

0 0