Eclipse下的开发因为是插件化的,所以一切都要尽可能的实行标准,而不是直接操作底层,就Tree来说,就需要使用TreeViewer,而不是Tree,但是使用封装后的组件往往有一些自定义的目标做不到,比如对一个TreeViewer setInput之后,因为input Model的改变,TreeViewer要对每个节点的路径进行计算,如果得到的element和原来的不一样,就会进行路径更新,放弃原有的路径。而Tree是一个多级化的组件,有折叠的状态存在,每一个TreeItem可以拥有自己的子节点。如果直接使用TreeViewer,然后想对TreeViewer的Tree直接进行操作实际上是不可能的。TreeViewer的节点是通过ContentProvider动态拿到的,所以当我们想直接操作某一个节点,比如想让它展开,或者获得它的子节点数目的时候,得到的结果都会和预期结果完全不一样,因为那个时候TreeItem的子节点并没有被自动创建。
那么如何对一个TreeViewer的TreeItem进行操作呢?通过以上的分析得知,我们首先要创建出该节点的子节点才行。TreeViewer里有一个方法:protected void createChildren(Widget widget),该方法是用来创建TreeItem的子节点的,可以看到它是一个protected方法,不允许外界访问的。我们可以在需要用到TreeViewer的地方,自己继承TreeViewer,覆写createChildren方法,把protected改成public。然后通过这个CustromTreeViewer,就可以自由控制子节点了。凡是我们需要操作TreeItem的地方,首先createChildren(item),然后item.setExpanded(true)或者item.getItems[]都可以正常使用了。
一般来说,当需要记录和恢复一个TreeViewer的状态的时候,这个方法就会显得非常有用处。