`
lizhensan
  • 浏览: 377732 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

TreeViewer的ContentProvider详解,以及Lazy载入

阅读更多

为了实现这样的效果: 
    载入的过程中,显示Pending。 
 

    载入完毕,Pending消失。 
 
    

我们先从基础的说起,先来看ITreeContentProvider 接口: 

Java代码  收藏代码
  1. public interface ITreeContentProvider {  
  2.     public Object[] getElements(Object inputElement) ;  
  3.     public Object[] getChildren(Object parentElement) ;  
  4.     public boolean hasChildren(Object element) ;  
  5.     // ...  
  6. }  

    getElements 表示在setInput(Object)的时候,如何从Object中得到一个数组,而使用这个数组去将树的第一层结点显示出来。这个方法只在setInput时才使用一次。 
    getChildren表示在每次展开树的节点时,如果得到下一级节点的值,当然,树的节点展开了一次就不会再调用这个方法了,因为在树节点对应的控件TreeItem中,已经创建好了子节点控件了。 
    hasChildren就是判断当前节点是否有子节点,有的话,就显示+号。 

ITreeContentProvider的使用类型可以分成3种(我自己分的,^-^)。 
1。简单模式 
2。Lazy Loader模式(简单) 
3。Lazy Loader模式(显示Pending) 


一. 简单模式 
其实就是在setInput的模型中,已经预先将所有的子模型都载入完毕,而不用再动态的载入子模型了。 
模型说明: 
    这个模型代表树节点,是支持父子结构的。当然,在Jface里面是有一个TreeNode的,org.eclipse.jface.viewers.TreeNode,相应的还提供了一个org.eclipse.jface.viewers.TreeNodeContentProvider。 
Java代码  收藏代码
  1. public class TreeNode {  
  2.     private TreeNode parent;  
  3.     private List<TreeNode> children = new ArrayList<TreeNode>();  
  4.     private Object value;  


ContentProvider代码: 
Java代码  收藏代码
  1. public class SimpleContentProvider implements ITreeContentProvider {  
  2. public Object[] getElements(Object inputElement) {  
  3.     return ((TreeNode) inputElement).getChildren().toArray();  
  4. }  
  5. public Object[] getChildren(Object parentElement) {  
  6.     return ((TreeNode) parentElement).getChildren().toArray();  
  7. }  
  8. public boolean hasChildren(Object element) {  
  9.     return ((TreeNode) element).getChildren().size() > 0;  
  10. }  


构建setInput的模型 
就是在构建模型的时候,将所有的子模型都加载好了: 
Java代码  收藏代码
  1. private TreeNode buildLazyContent() {  
  2.     TreeNode root = new TreeNode(null);  
  3.     TreeNode level_1_1 = new TreeNode("1.1");  
  4.     root.addChild(level_1_1);  
  5.     // ...  
  6.     return root;  
  7. }  


其他代码: 
Java代码  收藏代码
  1. viewer.setLabelProvider(new TreeViewerLabelProvider());  
  2. viewer.setContentProvider(new SimpleContentProvider());  
  3. viewer.setInput(this.buildSimpleContent());  



二. Lazy Load模式(简单) 
在setInput的模型中,只有最顶层的模型,再每次点击+的时间,将下一层的模型动态的载入,从而将树的子节点构造出来。也就是在getChildren中动态载入即可。 

ContentProvider代码。 
    注意getChildren 和hasChildren的方法实现,hasChildren返回true,表示需要给这个树节点显示+号。点击+号,getChildren会动态的载入子节点数据,这样就实现了Lazy Load了。 
Java代码  收藏代码
  1. public class SimpleLazyContentProvider implements ITreeContentProvider {  
  2.     public Object[] getChildren(Object parentElement) {  
  3.         TreeNode parent = (TreeNode) parentElement;  
  4.         this.loadChildren(parent);   
  5.         return parent.getChildren().toArray();  
  6.     }  
  7.     public boolean hasChildren(Object element) {  
  8.         return true;   
  9.     }  
  10.     private void loadChildren(TreeNode parent) {  
  11.         TreeNode child_1 = new TreeNode("1");  
  12.         parent.addChild(child_1);  
  13.           
  14.         TreeNode child_2 = new TreeNode("2");  
  15.         parent.addChild(child_2);  
  16.     }  



构建setInput的模型: 
    只需要构建第一层树节点即可,后面的就交给ContentProvider去处理。 
Java代码  收藏代码
  1. private TreeNode buildSimpleLazyContent() {  
  2.     TreeNode root = new TreeNode(null);  
  3.     TreeNode level_1_1 = new TreeNode("1.1");  
  4.     root.addChild(level_1_1);  
  5.     return root;  
  6. }  


其他代码: 
Java代码  收藏代码
  1. viewer.setLabelProvider(new TreeViewerLabelProvider());  
  2. viewer.setContentProvider(new SimpleLazyContentProvider());  
  3. viewer.setInput(this.buildSimpleLazyContent());  



三. Lazy Loader模式(显示Pending) 
   和模式是二一样的,都是点+载入子模型。但是,如果是需要长时间的加载,模式二会将界面卡住,而这个模式,再点击+号后,会先显示一个Pending树节点(并可以显示进度条),并看到随着数据一个一个载入树节点一个一个添加出来,所有数据都载入后,Pending树节点消失,这样用户体验就会好很多。在这个模式,需要用到很多其他的类,具体看代码: 

模型代码: 
1. 需要实现IDeferredWorkbenchAdapter接口。 
2. 注意fetchDeferredChildren方法。将载入子数据的过程放到了模型里面(很怪)。 
Java代码  收藏代码
  1. public class PendingTreeNode extends TreeNode implements IDeferredWorkbenchAdapter {  
  2.     public void fetchDeferredChildren(Object object, IElementCollector collector,  
  3.             IProgressMonitor monitor) {  
  4.         PendingTreeNode parent = (PendingTreeNode) object;  
  5.           
  6.         try {  
  7.             Thread.sleep(500);  
  8.         } catch (InterruptedException e) {  
  9.             e.printStackTrace();  
  10.         }  
  11.         PendingTreeNode node1 = new PendingTreeNode("1");  
  12.         parent.addChild(node1);  
  13.         collector.add(node1, monitor);  
  14.           
  15.         try {  
  16.             Thread.sleep(500);  
  17.         } catch (InterruptedException e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.         PendingTreeNode node2 = new PendingTreeNode("2");  
  21.         parent.addChild(node2);  
  22.         collector.add(node2, monitor);  
  23.     }  


ContentProvider代码。 
1. 添加了一个DeferredTreeContentManager,并使用该manager代理getChildren方法。 
2. hasChildren返回true。 
3. 修改了getElements方法。 
Java代码  收藏代码
  1. public class PendingLazyContentProvider implements ITreeContentProvider {  
  2.     private DeferredTreeContentManager manager;  
  3.       
  4.     public Object[] getChildren(Object parentElement) {  
  5.         return manager.getChildren(parentElement);  
  6.     }  
  7.     public boolean hasChildren(Object element) {  
  8.         return true;  
  9.     }  
  10.     public Object[] getElements(Object inputElement) {  
  11.         if (inputElement instanceof PendingTreeNode) {  
  12.             return ((PendingTreeNode) inputElement).getChildren().toArray();              
  13.         }   
  14.         return new Object[0];  
  15.     }  
  16.     public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {  
  17.         if (manager == null) {  
  18.             manager = new DeferredTreeContentManager(this, (TreeViewer) viewer);  
  19.         }  
  20.     }  
  21. }  


LabelProvider代码: 
1. 修改了getText方法。由于我们说中间会创建一个显示Pending的节点,这个节点就是PendingUpdateAdapter,需要特别指定显示的text。 
Java代码  收藏代码
  1. public class PendingTreeViewerLabelProvider extends LabelProvider {  
  2.     public String getText(Object obj) {  
  3.         if (obj instanceof TreeNode) {  
  4.             return ((TreeNode) obj).getValue().toString();  
  5.         } else if (obj instanceof PendingUpdateAdapter) {  
  6.             return ((PendingUpdateAdapter) obj).getLabel(null);   
  7.         }  
  8.         return obj.toString();  
  9.     }  


构建setInput的模型: 
1. 只需要预先放入根节点即可。子节点的载入就依赖于点击+号,lazy载入了。 
Java代码  收藏代码
  1. private PendingTreeNode buildPendingLazyContent() {  
  2.     PendingTreeNode root = new PendingTreeNode(null);  
  3.   
  4.     PendingTreeNode level_1_1 = new PendingTreeNode("1.1");  
  5.     root.addChild(level_1_1);  
  6.     return root;  
  7. }  



其他代码: 
Java代码  收藏代码
  1. viewer.setLabelProvider(new PendingTreeViewerLabelProvider());  
  2. viewer.setContentProvider(new PendingLazyContentProvider());  
  3. viewer.setInput(this.buildPendingLazyContent());  




四. 总结 
1. 简单模式适合于你一次性将数据全部载入,而后在setInput一次显示出来。 
2. Lazy Load模式(简单)适合于性能影响不大的点击+号Lazy的载入数据。 
3. Lazy Load模式(显示Pending)适合于载入过程比较长,为了提供用户交互而使用 
4. Lazy Load模式都存在着遍历的问题。因为有的模型的子节点还没有完全载入,而你却依赖所有这些子节点的时候,这时就必须在代码里面将所有子节点打开,让其载入所有子数据至最后一层,对于(简单)和(显示Pending)都可以这么去做。 
5. 还是4的情况,由于(显示Pending)是异步载入的,需要更复杂的判断,并基于线程去判断某节点是否载入完毕,等你自己去实现的时候,你会发现这是有多复杂的^-^ 


五. 其他相关的类 
org.eclipse.jface.viewers.TreeNode 
org.eclipse.jface.viewers.TreeNodeContentProvider 
org.eclipse.jface.viewers.ArrayContentProvider 
org.eclipse.ui.progress.IDeferredWorkbenchAdapter 
org.eclipse.ui.progress.DeferredTreeContentManager 

 

 

http://lggege.iteye.com/blog/442964

分享到:
评论

相关推荐

    SWT TreeViewer实例

    【SWT TreeViewer实例详解】 在Java编程领域,特别是开发桌面应用程序时,SWT(Standard Widget Toolkit)是一个广泛使用的库,它提供了丰富的图形用户界面组件。TreeViewer是SWT库中的一个关键组件,用于创建和...

    Eclipse开发经典教程-TreeViewer组件

    `TreeViewer`不仅能够直观地呈现树形结构的数据,还支持丰富的自定义功能,如节点的显示标签、响应事件以及图标显示等。本文将详细探讨`TreeViewer`组件的核心概念、构建步骤及其实现机制,特别是内容提供器(`...

    Treeviewer1.0

    【Treeviewer1.0】是一款基于Python 3.4编程语言、PyQt5图形界面库以及Matplotlib数据可视化库的决策树查看工具。这个工具专为解析和展示微软的决策树模型而设计,使得用户能够直观地理解并分析决策树模型的结果。...

    XML TreeViewer

    XML TreeViewer是一款专为XML开发人员设计的实用工具,它以树形结构展示XML文档,使得数据层次清晰、易于理解。对于处理复杂或大型XML文件的开发者来说,这是一个非常宝贵的辅助工具,因为它提供了直观的方式来浏览...

    swt Tree 例子项目代码

    下面我们将深入探讨`Tree`类以及与之相关的`TreeViewer`、`LabelProvider`等概念。 1. **`Tree`类**:`Tree`类是SWT中表示树形控件的类,它允许你创建具有可展开/折叠节点的视图。每个节点可以有任意数量的子节点,...

    treeviewer

    是一款针对后缀名为.tre .tree .nwk 等树文件的打开及编辑软件

    SWT控件2

    【标签】"源码"和"工具"暗示这篇内容可能包含有关如何在实际项目中应用TreeViewer的代码示例,以及可能涉及一些辅助工具或者库,用于帮助开发者更高效地使用TreeViewer。源码分析可能是博文的重点,通过实例代码解析...

    eclipse从入门到精通的treexiew代码

    3. **设置内容提供者(ContentProvider)**:内容提供者是数据模型与TreeViewer之间的桥梁,负责为每个节点提供数据。实现`ITreeContentProvider`接口,定义获取根节点、子节点以及是否叶子节点的方法。 ```java ...

    RCP资料 filterTreeViewer

    总之,"RCP资料 filterTreeViewer"这个主题涵盖的是Eclipse RCP应用中使用过滤功能的TreeViewer组件,这涉及到数据模型、用户交互以及过滤逻辑的实现。理解和掌握这些知识对于开发功能丰富的Eclipse RCP应用程序至关...

    rcp treeview的相关资料

    接下来,你可以设置TreeViewer的各种属性,如它的列、其列的标题和数据类型,以及是否允许用户编辑等。 2. **内容提供者(ContentProvider)** 为了填充TreeViewer,你需要实现`IContentProvider`接口。这个接口...

    treeview资料

    ### TreeViewer资料详解 #### 15.1 概述 在Eclipse Rich Client Platform (RCP)中,TreeViewer是一种非常重要的控件,用于显示层次结构的数据。它基于SWT的`Tree`控件,并且是JFace库的一部分。由于TreeViewer提供...

    TreeViewer:使用 D3.js 的交互式进化树查看器

    #TreeViewer 交互式进化树可视化 此 Web 服务旨在提供完全交互式的进化树查看器。 该项目仍处于重开发阶段,可能会频繁出现大规模更改。 要测试 TreeViewer 的基本版本,请单击。 依赖项包括 D3.js、Bootstrap 和 ...

    JFace-viewer

    **JFace Viewer 知识点详解** 在Java开发领域,特别是使用Eclipse RCP(Rich Client Platform)进行桌面应用开发时,JFace是不可或缺的一部分。JFace是SWT(Standard Widget Toolkit)的一个扩展,提供了更高级别的...

    RCP实现的带有复选框的Tree

    3. **定义内容提供者(ContentProvider)**:内容提供者是将数据模型映射到TreeViewer的接口。你需要实现IContentProvider接口,并为CheckboxTreeViewer提供实现`getChildren`和`hasChildren`方法的类。 ```java ...

    DataGrid Treeview Drag and drop

    综上所述,实现"DataGrid Treeviewer Drag and drop"需要理解.NET的拖放机制,掌握DataGrid和TreeViewer的事件处理,以及数据的序列化和反序列化。同时,要注意用户体验和性能优化,确保功能的健壮性。在这个过程中...

    CheckboxTreeViewer

    它可能包括了主类、数据模型类以及与用户交互的控制逻辑。 总的来说,CheckboxTreeViewer是Java GUI开发中用于展示可选树结构的组件,特别适合处理文件或目录结构的显示和选择。通过使用Java IO类,开发者可以轻松...

    eclipse 集成 JSON2XML Tree Viewer

    本篇文章将详细介绍如何在Eclipse中集成JSON2XML Tree Viewer插件,以及如何利用它将JSON文本转换为XML和树形视图。 首先,我们要了解JSON和XML的基本概念。JSON是一种轻量级的数据交换格式,易于人阅读和编写,...

    java 开发视图插件(View) eclipse

    你可以定义适配器(Adapter)或内容提供者(ContentProvider)来处理数据模型。 5. **交互逻辑**:视图中可能包含按钮、菜单项等交互元素。通过`Action`类创建操作,并在`IActionDelegate`中实现具体行为。然后将...

    Eclipse下SWT图形界面开发指南(1)

    从简单的“Hello, World”示例开始,逐步深入到使用 JFace 创建复杂窗口,以及如何使用 `TreeViewer` 和 `TableViewer` 显示各种类型的数据。这些基础知识为后续文章中的更高级主题奠定了基础。 #### 相关资源 - ...

Global site tag (gtag.js) - Google Analytics