实在是老土,自己都感觉老土,写了这么多程序,怎么还在搞什么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);
这样我们就完成了树型结构的领域模型的建立;