Eclipse设计实现可重用的SWT构件
2007-11-19 10:44:36 来源:论坛整理 作者:翁长河 点击:
本文从创建一个简单的SWT Tree Table开始,引入可重用的用户界面构件这个开发人员普遍关心的问题,然后分析Eclipse的用户界面的一些设计模式,循序渐进的向读者展示了如何设计实现一个精巧的高度可重用的TreeTable构件,最终通过增加一些扩展的功能显示了该构件强大的可扩展能力和灵活性。
WorkBenchAdapter对节点分类显示的。
图4:IWorkBenchAdapter 的类阶层结构

图4中可以明显看见WorkBenchAdapter类会将每个对象(文件,文件夹,项目)适配包浏览器中的树节点,如果我们想象树中的每个节点代表每一行数据(一个只有一列的表),那么这样一种设计模式就是完全按行来控制的行控制器设计模式,我们可以为不同类型的行数据创建不同的适配器,精确控制这些数据的表现形式,如背景色、前景色、字体等,只要你愿意,还可以增加一些菜单或者打开编辑器等丰富的功能。本文将借鉴Eclipse的这一模式来设计TreeTable的行控制功能。图4显示了对File,Folder和Project这三种不同类型的数据做不同的控制,我们的构件中,将能够根据对象而不是类型做更为精确的控制。本文将参考WorkBenchAdapter的设计实现TreeTable的行控制器。
3.创建可重用的TreeTable构件
基于以上的研究,我们实现了一个高度可重用的TreeTable构件,限于篇幅,我们只实现了能够说明问题的最关键的功能。
使用IField实现列控制
为了便于说明问题我们创建了一个简单版本的IField接口,参见图5。
图5:简化后的IField接口

同时实现一个通用的TreeTableLabelProvider类,它使用IField接口控制列的行为。
清单4:TreeTableLabelProvider的代码
public class TreeTableLabelProvider extends LabelProvider implements
ITableLabelProvider {
private IField[] fields;
public TreeTableLabelProvider(IField[] fields) {
this.fields = fields;
}
public Image getColumnImage(Object element, int columnIndex) {
if (element == null || fields == null || columnIndex < 0
|| columnIndex >= fields.length || fields[columnIndex] == null) {
return null;
}
return fields[columnIndex].getImage(element);
}
public String getColumnText(Object element, int columnIndex) {
if (element == null || fields[columnIndex] == null || fields == null
|| columnIndex < 0 || columnIndex > fields.length) {
return "";
}
return fields[columnIndex].getValue(element);
}
} |
我们还实现了一个TreeTableViewer,如清单5所示,TreeTableViewer会根据IField来创建TreeTable的column。
清单5:TreeTableViewer的代码
public class TreeTableViewer extends CheckboxTreeViewer {
private IField[] fields;
public TreeTableViewer(Tree tree,IField[] fields,
ITreeTableAdapterFactory adapterFactory) {
super(tree);
this.fields =fields;
super.setContentProvider(new TreeTableContentProvider(adapterFactory));
super.setLabelProvider(new TreeTableLabelProvider(fields));
createColumns();
}
public void setTableInput(Object[] input) {
super.setInput(input);
}
protected void createColumns() {
IField[] fields = getFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i] != null) {
TreeColumn tc = new TreeColumn(getTree(), SWT.NONE);
tc.setText(fields[i].getColumnHeaderText());
tc.setWidth(fields[i].getPreferredWidth());
tc.setData(fields[i]);
}
}
}
public IField[] getFields() {
return fields;
}
} |