TableViewer组件
JFace中提供了TableViewer组件,用TableViewer来表示表格。TableViewer 和TreeViewer类似,它也提供了内容提供器(IStructuredContentProvider)和标签提供器(ITableLabelProvider),用来组织表格的信息。
TableViewer构建步骤
TableViewer中主要通过内容提供器(IStructuredContentProvider)和标签提供器(ITable- LabelProvider)组织表中单元格的显示信息。TableViewer构建步骤如下。
1. 创建TableViewer对象,例如“tableViewer = new TableViewer(table);”,其中table是SWT中Table对象。
2. 设定内容管理器,例如“tableViewer.setContentProvider(contentProvider);”。
3. 设定标签提供器,例如“tableViewer.setLabelProvider(labelProvider);”。
4. 设定TableViewer的输入数据,例如“tableViewer.setInput("root");”(用户可以通过输入数据构建表)。
另外,用户可以添加排序器和过滤器对表格数据进行排序和过滤,后面将通过实例介绍排序器和过滤器。
TableViewer内容提供器(IStructuredContentProvider)
TableViewer中的内容管理器比较简单,用户可以通过实现getElements返回表格的所有数据。
getElements定义为“public Object[] getElements(Object inputElement)”,返回Object[]对象数组,其中数组中每一个对象代表表格的一列。当TableViewer输入数据后,内容管理器将根据输入数据构造表格对象数据,如下代码所示。
public Object[] getElements(Object inputElement) {
//通过输入的数据建表
Vector v = (Vector) inputElement;
return v.toArray();
}
其中,输入数据inputElement为Vector类型的变量,通过“v.toArray();”返回对象数组。
TableViewer标签提供器(ITableLabelProvider)
TableViewer中的标签提供器主要负责每个单元格中文本和图标的显示。ITableLabelProvider接口要求实现getColumnText和getColumnImage两个主要的方法,getColumnText返回指定单元格的显示文本,getColumnImage返回指定单元格的显示图标,解释如下。
1. getColumnText:此函数定义为“public String getColumnText(Object element, int columnIndex)”,其中element表示单元格所在行的对象,columnIndex表示单元格所在的列,返回显示的文本。如下代码返回Bug对象的某特定列的显示文本。
public String getColumnText(Object element, int columnIndex) {
Bug bug = (Bug) element;
switch (columnIndex) {
case 0:
return bug.id;
case 1:
return bug.summary;
case 2:
return bug.assignedTo;
case 3:
return bug.isSolved ? "YES" : "NO";
}
return null;
}
2. getColumnImage:此函数定义为“public Image getColumnImage(Object element, int columnIndex)”,其中element表示单元格所在行的对象,columnIndex表示单元格所在的列,返回此单元格的显示图标。如下代码返回Bug对象的某特定列的显示图标。
public Image getColumnImage(Object element, int columnIndex) {
if (columnIndex == 0)
return bugIcon;
return null;
}
从上面代码可以看出,只有第一列显示图标,其他列不显示图标。
TableViewer实例
本节的实例为一个Bug列表实例(BugTrackerTableViewer),程序的功能如下。
1. 在窗口中通过ToolBar建立工具栏,并通过ToolBarManager添加相应的Action到工具栏中。
2. 在表格中设置内容管理器和标签管理器。
3. 在表格的每一列添加排序器。当用户单击列头时,排序器将按列排序。排序器中主要通过compare方法比较两行(即两个对象)中的特定列单元格数据大小,返回比较后表格排列的顺序。
4. 通过工具栏的Action(actionShowUnsolvedOnly)添加或删除过滤器,过滤器将根据过滤条件选择出符合要求的行(即对象)。
另外,程序中将在运行时加载上次存储的Bug列表,用户也可以保存当前的Bug列表,程序如例程1所示。
例程1 BugTrackerTableViewer.java
/**
* 为了节省篇幅,把所有的import类注释了
* 读者可以通过ctrl+shift+o快捷键,自动引入所依赖的类
* */
public class BugTrackerTableViewer {
// 内部类Bug,代表一个BUG显示
public static class Bug {
public String id;
public String summary;
public String assignedTo;
public boolean isSolved;
public Bug(String id, String summary, String assignedTo,
boolean isSolved) {
this.id = id;
this.summary = summary;
this.assignedTo = assignedTo;
this.isSolved = isSolved;
}
public static Vector loadBugs(File file) {
Vector v = new Vector();
DataInputStream in = null;
try {
if (!file.exists())
return v;
in = new DataInputStream(new FileInputStream(file));
while (true) {
String id = in.readUTF();
String summary = in.readUTF();
String assignedTo = in.readUTF();
boolean solved = in.readBoolean();
v.add(new Bug(id, summary, assignedTo, solved));
}
} catch (IOException ioe) {
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return v;
}
}
Display display = new Display();
Shell shell = new Shell(display);
Table table;
TableViewer tableViewer;
Vector bugs;
/**
* 读者可以通过图片创建自己的Image 例如:Image bugIcon = new Image(shell.getDisplay(),
* "icons/mybug.gif");
*/
Image bugIcon = WorkbenchImages
.getImage(IWorkbenchGraphicConstants.IMG_OBJ_SIGNED_YES);
String[] colNames = new String[] { "ID", "Summary", "Assigned to", "Solved" };
// 实现表格的排序器
class BugSorter extends ViewerSorter {
private String property;
private int propertyIndex;
public BugSorter(String sortByProperty) {
for (int i = 0; i < colNames.length; i++) {
if (colNames[i].equals(sortByProperty)) {
this.property = sortByProperty;
this.propertyIndex = i;
return;
}
}
throw new IllegalArgumentException("Unrecognized property: "
+ sortByProperty);
}
// 比较e1和e2的大小
public int compare(Viewer viewer, Object e1, Object e2) {
Bug bug1 = (Bug) e1;
Bug bug2 = (Bug) e2;
switch (propertyIndex) {
case 0:
return bug1.id.compareTo(bug2.id);
case 1:
return bug1.summary.compareTo(bug2.summary);
case 2:
return bug1.assignedTo.compareTo(bug2.assignedTo);
case 3:
if (bug1.isSolved == bug2.isSolved)
return 0;
if (bug1.isSolved)
return 1;
else
return -1;
default:
return 0;
}
}
}
public BugTrackerTableViewer() {
// 添加工具栏的相应Action
// 添加新建按钮的Action
Action actionAddNew = new Action("New bug") {
public void run() {
// Append.
Bug bug = new Bug("", "", "", false);
bugs.add(bug);
tableViewer.refresh(false);
}
};
Action actionDelete = new Action("Delete selected") {
public void run() {
IStructuredSelection selection = (IStructuredSelection) tableViewer
.getSelection();
Bug bug = (Bug) selection.getFirstElement();
if (bug == null) {
System.out.println("Please select an item first. ");
return;
}
MessageBox messageBox = new MessageBox(shell, SWT.YES | SWT.NO);
messageBox.setText("Confirmation");
messageBox
.setMessage("Are you sure to remove the bug with id #"
+ bug.id);
if (messageBox.open() == SWT.YES) {
bugs.remove(bug);
tableViewer.refresh(false);
}
}
};
Action actionSave = new Action("Save") {
public void run() {
saveBugs(bugs);
}
};
// 添加表的过滤器
final ViewerFilter filter = new ViewerFilter() {
public boolean select(Viewer viewer, Object parentElement,
Object element) {
if (!((Bug) element).isSolved)
return true;
return false;
}
};
Action actionShowUnsolvedOnly = new Action("Show unsolved only") {
public void run() {
if (!isChecked())
tableViewer.removeFilter(filter);
else
tableViewer.addFilter(filter);
}
};
actionShowUnsolvedOnly.setChecked(false);
ToolBar toolBar = new ToolBar(shell, SWT.RIGHT | SWT.FLAT);
ToolBarManager manager = new ToolBarManager(toolBar);
// 添加工具项,并把工具项关联到相应的Action
manager.add(actionAddNew);
manager.add(actionDelete);
manager.add(new Separator());
manager.add(actionSave);
manager.add(new Separator());
manager.add(actionShowUnsolvedOnly);
manager.update(true);
shell.setLayout(new GridLayout());
table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
TableColumn tcID = new TableColumn(table, SWT.LEFT);
tcID.setText(colNames[0]);
TableColumn tcSummary = new TableColumn(table, SWT.NULL);
tcSummary.setText(colNames[1]);
TableColumn tcAssignedTo = new TableColumn(table, SWT.NULL);
tcAssignedTo.setText(colNames[2]);
TableColumn tcSolved = new TableColumn(table, SWT.NULL);
tcSolved.setText(colNames[3]);
tcID.setWidth(60);
tcSummary.setWidth(200);
tcAssignedTo.setWidth(80);
tcSolved.setWidth(50);
tableViewer = new TableViewer(table);
tableViewer.getTable().setLinesVisible(true);
tableViewer.getTable().setHeaderVisible(true);
tableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
// 设定表的内容管理器
tableViewer.setContentProvider(new IStructuredContentProvider() {
// 获得所有对象
public Object[] getElements(Object inputElement) {
// 通过输入的数据建表
Vector v = (Vector) inputElement;
return v.toArray();
}
public void dispose() {
System.out.println("Disposing ...");
}
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
System.out.println("Input changed: ld=" + oldInput + ", new="
+ newInput);
}
});
// 设定表的标签管理器
tableViewer.setLabelProvider(new ITableLabelProvider() {
public Image getColumnImage(Object element, int columnIndex) {
if (columnIndex == 0)
return bugIcon;
return null;
}
// 获得列的显示文本
public String getColumnText(Object element, int columnIndex) {
Bug bug = (Bug) element;
switch (columnIndex) {
case 0:
return bug.id;
case 1:
return bug.summary;
case 2:
return bug.assignedTo;
case 3:
return bug.isSolved ? "YES" : "NO";
}
return null;
}
public void addListener(ILabelProviderListener listener) {
}
public void dispose() {
}
public boolean isLabelProperty(Object element, String property) {
return false;
}
public void removeListener(ILabelProviderListener listener) {
}
});
// 设定单元格编辑器
tableViewer.setColumnProperties(colNames);
CellEditor[] cellEditors = new CellEditor[4];
cellEditors[0] = new TextCellEditor(table);
cellEditors[1] = cellEditors[0];
cellEditors[2] = cellEditors[0];
cellEditors[3] = new CheckboxCellEditor(table);
tableViewer.setCellEditors(cellEditors);
// 设定单元格修改器
tableViewer.setCellModifier(new ICellModifier() {
public boolean canModify(Object element, String property) {
return true;
}
public Object getValue(Object element, String property) {
int index = -1;
for (int i = 0; i < colNames.length; i++) {
if (colNames[i].equals(property)) {
index = i;
break;
}
}
Bug bug = (Bug) element;
switch (index) {
case 0:
return bug.id;
case 1:
return bug.summary;
case 2:
return bug.assignedTo;
case 3:
return new Boolean(bug.isSolved);
}
return null;
}
public void modify(Object element, String property, Object value) {
System.out.println("Modify: " + element + ", " + property
+ ", " + value);
int index = -1;
for (int i = 0; i < colNames.length; i++) {
if (colNames[i].equals(property)) {
index = i;
break;
}
}
Bug bug = null;
if (element instanceof Item) {
TableItem item = (TableItem) element;
bug = (Bug) item.getData();
} else {
bug = (Bug) element;
}
switch (index) {
case 0:
bug.id = (String) value;
break;
case 1:
bug.summary = (String) value;
break;
case 2:
bug.assignedTo = (String) value;
break;
case 3:
bug.isSolved = ((Boolean) value).booleanValue();
break;
}
tableViewer.update(bug, null);
}
});
// 设定表格的排序方式
// 单击第一列列头按第一列排序
tcID.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
tableViewer.setSorter(new BugSorter(colNames[0]));
}
});
// 单击第二列列头按第二列排序
tcSummary.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
tableViewer.setSorter(new BugSorter(colNames[1]));
}
});
// 单击第三列列头按第三列排序
tcAssignedTo.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
tableViewer.setSorter(new BugSorter(colNames[2]));
}
});
// 单击第四列列头按第四列排序
tcSolved.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
tableViewer.setSorter(new BugSorter(colNames[3]));
}
});
// 从文件中读取Bug记录
bugs = Bug.loadBugs(new File("bugs.dat"));
// 把bugs作为表格的输入
tableViewer.setInput(bugs);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
// 保存当前的Bug记录
private void saveBugs(Vector v) {
DataOutputStream ut = null;
try {
File file = new File("bugs.dat");
out = new DataOutputStream(new FileOutputStream(file));
for (int i = 0; i < v.size(); i++) {
Bug bug = (Bug) v.elementAt(i);
out.writeUTF(bug.id);
out.writeUTF(bug.summary);
out.writeUTF(bug.assignedTo);
out.writeBoolean(bug.isSolved);
}
} catch (IOException ioe) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new BugTrackerTableViewer();
}
}
上例为表格添加了过滤器(ViewerFilter)和排序器(BugSorter),用户可以单击表格的列头按此列进行排序。另外,还能够通过工具栏按钮过滤掉已解决的Bug信息。程序运行效果如图1所示。
图1 TableViewer组件
TableViewer的功能比较强大,在复杂的应用中可以用它代替SWT中的Table组件,实现表格的完美展现。
除了TreeViewer和TableViewer组件外,JFace中还封装了ListViewer等组件,用户可以直接使用这些组件实现自己的功能。
提示:所有的Viewer组件都封装了SWT中组件的实现,例如TreeViewer封装了Tree组件,可以通过Viewer组件得到对应的SWT组件(“getTree”),这可能在窗口布局或直接处理Viewer中的SWT窗口时会使用到。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13081368/viewspace-365969/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/13081368/viewspace-365969/