Content Provider的使用

实在是老土,自己都感觉老土,写了这么多程序,怎么还在搞什么Content Provider。可是换个角度来看,这么长时间,你真的理解了么,每一次写程序的时候不都是从网上找一个改改么,是该好好总结一下了。

Content Provider是viewer表示的模型和viewer本身之间的一个调停者;IContentProvider是所有Content Provider的父接口,如果你想为一个Viewer提供响应的Content Provider,那么必须继承这个接口;这个接口有两个函数:

1、public void dispose();这个函数在viewer被dispose的时候调用;在调用这个函数的过程中,viewer不应该被改变,因为它已经处于一个正在dispose的过程中;

2、public void inputChanged(Viewer viewer, Object oldInput, Object newInput);这个函数用来通知content provider,给定的viewer的输入已经变成了一个新的元素;参数viewer就是viewer,oldInput是老的input element,而newInput是新的input element;

从网上查找Eclipse的帮助我们可以知道,事实上IContentProvider的子接口还是真多,有一些我还真的不知道是干吗用的,但是我们常常使用的一个针对TableViewer和TreeViewer的子接口就是IStructuredContentProvider。

IStructuredContentProvider接口是为结构化的viewer提供内容的,在这个接口中提供了一个函数:
public Object[] getElements(Object inputElement);当我们定义Content Provider类的时候,需要将inputElement转换成一个数组返回;而inputElement恰恰就是我们的viewer在调用setInput函数中给定的那个input;

这就明白了,每当我们调用setInput函数时,系统将会调用getElements函数,将我们给定的那个input转换为一个数组,数组中的每一项就是我们模型领域的一个对象实例;然后再通过Label Provider,这个实例中的各个属性就以我们需要的数据形式显示在viewer中了;因此最简便的方法是定义一个ArrayList变量存储模型领域的对象实例,然后将这个变量作为viewer的输入,而ArrayList转换为数组是非常方便的,只要调用toArray()函数就可以直接获得Object[]数组了;

再罗嗦一下:

1、定义模型领域数据,可以是一个Java Bean;

2、定义ArrayList变量存储模型领域实例对象;

3、定义内容提供者类继承自IStructuredContentProvider,在getElements函数中将inputElement转换为一个数组;(也就是将inputElement转换为ArrayList类型然后调用toArray()函数;

4、设定viewer的Content Provider为第3步中的类,然后调用setInput方法将ArrayList作为参数;

当然:一定要有Label Provider。

 

惭愧,昨天太晚了,没有好好地爬一下TreeViewer的源码!

对于TreeViewer来说,它的Content Provider可不能仅仅是IStructuredContentProvider,而应该是这个接口的子接口:ITreeContentProvider或者ITreePathContentProvider才行。而对于TableViewer和ListViewer来说IStructuredContentProvider就可以了。那么好吧,让我们Look Look这两个接口的定义吧。

接口一:ITreeContentProvider,这个接口提供了三个函数;
1、public Object[] getChildren(Object parentElement);这个函数用来获得给定的父节点的所有子节点;而IStructuredContentProvider.getElements在这里的功能是获得tree viewer的根节点;
2、public Object getParent(Object element);这个函数用来获得给定节点的父节点;
3、public boolean hasChildren(Object element);这个函数用来判断给定节点是否具有子节点;

明白了上面的东西,那么对于TreeViewer来说,模型域的数据应该如何组织呢?这绝对是一个需要总结的问题。还是来一个例子吧:

第一步:定义模型域类;
class Node {
  private String name;
  private Vector subCategories;
  private Node parent;
  public Node(String name, Node parent) {
  this.name = name;
  this.parent = parent;
  if (parent != null)
    parent.addSubCategory(this);
  }

  public Vector getSubCategories() {
    return subCategories;
  }

  private void addSubCategory(Node subcategory) {
    if (subCategories == null)
      subCategories = new Vector();
    if (!subCategories.contains(subcategory))
      subCategories.add(subcategory);
  }

  public String getName() {
    return name;
  }

  public Node getParent() {
    return parent;
  }
}

第二步:定义container包含所有的节点;
static Vector nodes = new Vector();

 

第三步:container中建立数据,这一步需要真正的业务逻辑的配合才行,说白了就是建立一个树型结构;

Node category = new Node("A"null);
nodes.add(category);
category = new Node("a1", category);
new Node("a11", category);
new Node("a12", category);
category = new Node("B"null);
nodes.add(category);
new Node("b1", category);
new Node("b2", category);

这样我们就完成了树型结构的领域模型的建立;

posted on 2010-01-25 23:48  wayne.wang  阅读(1712)  评论(0编辑  收藏  举报

导航