您的位置:首页 > 其它

Swt/Jface tableviewer总结

2012-10-26 22:47 507 查看

Swt/Jface tableviewer总结(主要参考)(一)

Eclipse JFace Table - Tutorial

1、Table of Contents

http://www.vogella.de/articles/EclipseJFaceTable/article.html

2、

lipse JFace Table - Advanced Tutorial

http://www.vogella.de/articles/EclipseJFaceTableAdvanced/article.html

3、RCP之病人信息系统开发总结(总参考)

参考:http://www.cnblogs.com/yinger/default.html?page=2


http://blog.csdn.net/folio/article/details/7328135

Swt/Jface tableViewer入门教程一(显示tableViewer)

1,简单显示,表格的式样见注释中的内容

import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class TestTableViewer {
private static Table table;
/**
* Launch the application
* @param args
*/
public static void main(String[] args) {
final Display display = Display.getDefault();
final Shell shell = new Shell();
shell.setSize(500, 375);
shell.setText("SWT Application");
//注意这里,SWT.NULTI代表可以选择多行,SWT.FULL_SELECTION代表可以整行选择,SWT.BORDER边框,SWT.V_SCROLL ,SWT.H_SCROLL滚动条
final TableViewer tableViewer = new TableViewer(shell, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);

table = tableViewer.getTable();
table.setLinesVisible(true);
table.setHeaderVisible(true);
table.setBounds(97, 79, 373, 154);

final TableColumn newColumnTableColumn = new TableColumn(table, SWT.NONE);
newColumnTableColumn.setWidth(39);
newColumnTableColumn.setText("ID");

final TableColumn newColumnTableColumn_1 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_1.setWidth(85);
newColumnTableColumn_1.setText("姓名");

final TableColumn newColumnTableColumn_2 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_2.setWidth(41);
newColumnTableColumn_2.setText("性别");

final TableColumn newColumnTableColumn_3 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_3.setWidth(43);
newColumnTableColumn_3.setText("年龄");

final TableColumn newColumnTableColumn_4 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_4.setWidth(126);
newColumnTableColumn_4.setText("创建日期");

shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
}


2,加入布局

显示的效果不好,我们要加入布局,让view填充整个画面,在shell.open()后加上

ok,效果达到

3,为TableViewer加上数据,光突突的样子不好看。这里是demo所以不再从数据库里边取数据了。自己构造一个List用来做数据。实际使用中也是这么使用,不过不同的是这里是随意构造的list,而显示实际使用中是从数据库取出数据构造list.

(1)构造一个people类,同时给People类提供一个构造假数据的方法getPeople()

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class People{
private Long id;
private String name;
private String sex;
private Integer age;
private Date createDate;
public People(Long id,String name,String sex,Integer age,Date createDate){
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.createDate = createDate;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public static List getPeople(){
List list = new ArrayList();
int n = 30;
for(int i=1;i<n;i++){
Long id = new Long(i);
String name = "张"+i;
String sex = "男";
if((i%2) == 0){
sex = "女";
}
Integer age;
if(i<10){
age = new Integer(i*10);
}else if(i>10 && i<100){
age = new Integer(i);
}else if(i>100 && i<1000){
age = new Integer(i/10);
}else{
age = new Integer(22);
}
Date createDate = new Date();
People people = new People(id,name,sex,age,createDate);
list.add(people);
}
return list;
}
}


(2)给tableViewer提供内容器(IStructuredContentPorvider)和标签器(ITableLabelProvider)

如果想一个tableviewer显示数据,那必须给它提供内容器和标签器,内容器的作用是从List(也可以是其他的集合类)中提取出一个对象(例如People对应着表格的一行,数据库的一条记录),标签器的作用是从一个对象中提取出一个字段(例如年龄,对应着表格中的一个单元格,数据库中某一列的一个值)下边是内容器和标签器的代码:

内容器:

import java.util.List;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;

public class ContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object inputElement) {
if(inputElement instanceof List){
return ((List)inputElement).toArray();
}else{
return new Object[0];
}
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}


标签器:


import java.text.SimpleDateFormat;

import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;

public class TableLabelProvider extends LabelProvider implements ITableLabelProvider {
public String getColumnText(Object element, int columnIndex) {
if (element instanceof People){
People p = (People)element;
if(columnIndex == 0){
return p.getId().toString();
}else if(columnIndex == 1){
return p.getName();
}else if (columnIndex ==2){
return p.getSex();
}else if (columnIndex == 3){
return p.getAge().toString();
}else if (columnIndex == 4){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(p.getCreateDate());
}
}
return null;
}
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
}
注意这里:extends LabelProvider,为什么要加这个呢? 因为如果不加这个,因为实现 ITableLabelProvider 的缘故我们还要写四个空函数,而我们本身不需要在这四个空函数中实现什么,所以让它继承自LabelProvider,就可以避免四个空函数。

(3)把标签器和内容器给tableviewer

在shell.open()前边加上这几行

//设置内容器
tableViewer.setContentProvider(new ContentProvider());
//设置标签器
tableViewer.setLabelProvider(new TableLabelProvider());
//把数据集合给tableView
tableViewer.setInput(People.getPeople());
//这样利用内容器和标签器就能从setInput得到的数据集合分解出显示表格需要的数据。这是一个典型的mvc的实现.

4,样式改变

如果想在每一列前加入一个checkbox

只需要在开始的式样中加入SWT.CHECK

好了到此一个简单的样子选择出来了,但这仅仅是开始,下边将继续介绍按列排序、过滤器、行的颜色设置、在表格上直接编辑等功能

附上source:http://www.blogjava.net/Files/dreamstone/jface-1.rar

Swt/Jface tableViewer入门教程二(让TableViewer按照列排序)

有一个功能是我们常使用的,就是在列的头上点击一下,整个表的记录按照这个列来排序,再点击一下按照这个列的反序来排序。那JFace是如何实现这个功能的呢?

在JFace中是通过一个排序器来实现的,就是ViewerSorter下边写出详细的步骤

一、定义一个sorter继承自ViewerSorter

import java.util.Date;

import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;

public class Sorter extends ViewerSorter {
private static final int ID = 1;
private static final int NAME = 2;
private static final int SEX = 3;
private static final int AGE = 4;
private static final int CREATE_DATE = 5;

public static final Sorter ID_ASC = new Sorter(ID);
public static final Sorter ID_DESC = new Sorter(-ID);
public static final Sorter NAME_ASC = new Sorter(NAME);
public static final Sorter NAME_DESC = new Sorter(-NAME);
public static final Sorter SEX_ASC = new Sorter(SEX);
public static final Sorter SEX_DESC = new Sorter(-SEX);
public static final Sorter AGE_ASC = new Sorter(AGE);
public static final Sorter AGE_DESC = new Sorter(-AGE);
public static final Sorter CREATE_DATE_ASC = new Sorter(CREATE_DATE);
public static final Sorter CREATE_DATE_DESC = new Sorter(-CREATE_DATE);

private int sortType ;
private Sorter(int sortType){
this.sortType = sortType;
}
public int compare(Viewer viewer, Object e1, Object e2) {
People p1 = (People)e1;
People p2 = (People)e2;
switch(sortType){
case ID:{
Long l1 = p1.getId();
Long l2 = p2.getId();
return l1.compareTo(l2);
}
case -ID:{
Long l1 = p1.getId();
Long l2 = p2.getId();
return l2.compareTo(l1);
}
case NAME:{
String s1 = p1.getName();
String s2 = p2.getName();
return s1.compareTo(s2);
}
case -NAME:{
String s1 = p1.getName();
String s2 = p2.getName();
return s2.compareTo(s1);
}
case SEX:{
String s1 = p1.getSex();
String s2 = p2.getSex();
return s1.compareTo(s2);
}
case -SEX:{
String s1 = p1.getSex();
String s2 = p2.getSex();
return s2.compareTo(s1);
}
case AGE:{
Integer i1 = p1.getAge();
Integer i2 = p2.getAge();
return i1.compareTo(i2);
}
case -AGE:{
Integer i1 = p1.getAge();
Integer i2 = p2.getAge();
return i2.compareTo(i1);
}
case CREATE_DATE:{
Date d1 = p1.getCreateDate();
Date d2 = p2.getCreateDate();
d1.compareTo(d2);
}
case -CREATE_DATE:{
Date d1 = p1.getCreateDate();
Date d2 = p2.getCreateDate();
d2.compareTo(d1);
}
}
return 0;
}
}


二、在TableViewer上,为每一列加入事件监听器类似这样的结构

newColumnTableColumn.addSelectionListener(new SelectionAdapter(){
boolean asc = true;
public void widgetSelected(SelectionEvent e){
tableViewer.setSorter(asc?Sorter.ID_ASC:Sorter.ID_DESC);
asc = !asc;
}
});


都加入后TestTableViewer的结果:

import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class TestTableViewer {
private static Table table;
/** *//**
* Launch the application
* @param args
*/
public static void main(String[] args) {
final Display display = Display.getDefault();
final Shell shell = new Shell();
shell.setSize(500, 375);
shell.setText("SWT Application");
//
final TableViewer tableViewer = new TableViewer(shell, SWT.CHECK|SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);

table = tableViewer.getTable();
table.setLinesVisible(true);
table.setHeaderVisible(true);
table.setBounds(97, 79, 373, 154);

final TableColumn newColumnTableColumn = new TableColumn(table, SWT.NONE);
newColumnTableColumn.setWidth(39);
newColumnTableColumn.setText("ID");
//加入事件监听器
newColumnTableColumn.addSelectionListener(new SelectionAdapter(){
boolean asc = true;
public void widgetSelected(SelectionEvent e){
tableViewer.setSorter(asc?Sorter.ID_ASC:Sorter.ID_DESC);
asc = !asc;
}
});

final TableColumn newColumnTableColumn_1 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_1.setWidth(85);
newColumnTableColumn_1.setText("姓名");
//        加入事件监听器
newColumnTableColumn_1.addSelectionListener(new SelectionAdapter(){
boolean asc = true;
public void widgetSelected(SelectionEvent e){
tableViewer.setSorter(asc?Sorter.NAME_ASC:Sorter.NAME_DESC);
asc = !asc;
}
});

final TableColumn newColumnTableColumn_2 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_2.setWidth(41);
newColumnTableColumn_2.setText("性别");
//        加入事件监听器
newColumnTableColumn_2.addSelectionListener(new SelectionAdapter(){
boolean asc = true;
public void widgetSelected(SelectionEvent e){
tableViewer.setSorter(asc?Sorter.SEX_ASC:Sorter.SEX_DESC);
asc = !asc;
}
});

final TableColumn newColumnTableColumn_3 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_3.setWidth(43);
newColumnTableColumn_3.setText("年龄");
//        加入事件监听器
newColumnTableColumn_3.addSelectionListener(new SelectionAdapter(){
boolean asc = true;
public void widgetSelected(SelectionEvent e){
tableViewer.setSorter(asc?Sorter.AGE_ASC:Sorter.AGE_DESC);
asc = !asc;
}
});

final TableColumn newColumnTableColumn_4 = new TableColumn(table, SWT.NONE);
newColumnTableColumn_4.setWidth(126);
newColumnTableColumn_4.setText("创建日期");
//        加入事件监听器
newColumnTableColumn_4.addSelectionListener(new SelectionAdapter(){
boolean asc = true;
public void widgetSelected(SelectionEvent e){
tableViewer.setSorter(asc?Sorter.CREATE_DATE_ASC:Sorter.CREATE_DATE_DESC);
asc = !asc;
}
});

tableViewer.setContentProvider(new ContentProvider());
tableViewer.setLabelProvider(new TableLabelProvider());
tableViewer.setInput(People.getPeople());

shell.open();
shell.setLayout(new FillLayout());
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
}



试一下结果是不是出来了?

好了,最后解释几点:

1,sorter中利用了jdk的compareTo来实现比较,当然你也可以根据自己的需求来实现。

2, sorter中利用了"-"符号来得到正负数字,用来表现升序、降序。

source下载:http://www.blogjava.net/Files/dreamstone/jface-2.rar

Swt/Jface tableViewer入门教程三(加入在表格上直接编辑数据)

前边实现了一个表格的基本功能,但这并不够好,能否为表格实现一些更好的功能呢?答案是肯定的。下边我们来加入直接编辑的功能。

一、要实现这个功能必须提供一个实现ICellModifier的类。内容如下

import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.TableItem;

public class MyCellModifier implements ICellModifier{
private TableViewer tv;
public static String[] NAMES ={"张三","李四","小红","翠花"};

public MyCellModifier(TableViewer tv){
this.tv = tv;
}
public boolean canModify(Object element, String property) {
return true;
}

public Object getValue(Object element, String property) {
People p = (People)element;
if(property.equals("name")){
return new Integer(getNameIndex(p.getName()));
}else if(property.equals("sex")){
return new Boolean(p.getSex().equals("男"));
}else if(property.equals("age")){
return String.valueOf(p.getAge());
}
throw new RuntimeException("error column name : " + property);
}
private int getNameIndex(String name){
for(int i=0;i<NAMES.length;i++){
if(NAMES[i].equals(name)){
return i;
}
}
return -1;
}

public void modify(Object element, String property, Object value) {
TableItem item = (TableItem)element;
People p = (People)item.getData();
if (property.equals("name")){
Integer comboIndex = (Integer)value;
if(comboIndex.intValue() == -1){
return ;
}
String newName = NAMES[comboIndex.intValue()];
p.setName(newName);
}else if(property.equals("sex")){
Boolean newValue = (Boolean)value;
System.out.println(newValue);
if(newValue.booleanValue()){
p.setSex("男");
}else{
p.setSex("女");
}
}else if (property.equals("age")){
String newValue = (String)value;
if(newValue.equals("")){
return ;
}
Integer newAge = new Integer(newValue);
p.setAge(newAge);
}else{
throw new RuntimeException("错误列名:" + property);
}
tv.update(p, null);
}

}


二、好了,有了这个类,下一部就是如何把它和TestTableViewer关联起来,在TestTableViewer中setInput()后加入如下内容

tableViewer.setColumnProperties(new String[]{"id","name","sex","age","createDate"});
CellEditor[] cellEditor = new CellEditor[5];
cellEditor[0] = null;
cellEditor[1] = new ComboBoxCellEditor(tableViewer.getTable(),MyCellModifier.NAMES,SWT.READ_ONLY);
cellEditor[2] = new CheckboxCellEditor(tableViewer.getTable());
cellEditor[3] = new TextCellEditor(tableViewer.getTable());
cellEditor[4] = null;
tableViewer.setCellEditors(cellEditor);
ICellModifier modifier = new MyCellModifier(tableViewer);
tableViewer.setCellModifier(modifier);


我们让名字这一列用下拉条来编辑,让性别这一列变成类似checkbox的操作,让年龄这一类变成直接输入

ok,尝试一下。

三、问题出现,如果年龄的地方我们输入一个非数字呢,所以为了安全起见,我们加入一个验证器,禁止用户输入非数字

在上边的内容下加入

Text text = (Text)cellEditor[3].getControl();
text.addVerifyListener(new VerifyListener(){
public void verifyText(VerifyEvent e){
String inStr = e.text;
if (inStr.length() > 0){
try{
Integer.parseInt(inStr);
e.doit = true;
}catch(Exception ep){
e.doit = false;
}
}
}
});


好了,再试试是否不能输入非整数了?解决。其实还是有些问题的,试着输入个0,呵呵。这里就需要你自己按照自己的实际需求来实现了。

但作为demo这个的目的已经达到了。

source下载:http://www.blogjava.net/Files/dreamstone/jface-3.rar

Swt/Jface tableviewer入门教程四(加入filter ,改变行的颜色)

如果我们想根据某一列来过滤记录,如何实现呢?很简单,定义一个过滤器filter。这里只演示定义一个过滤器的情况。

现实中你可以定义多个灵活的过滤器,通过替换过滤器来实现各种各样的过滤。

一、过滤器代码:

import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;

public class MyFilter extends ViewerFilter {
public boolean select(Viewer viewer, Object parentElement, Object element) {
People p = (People) element;
return p.getName().startsWith("张1");
}
}


然后在testTableViewer的shell.open前加入这个过滤器
tableViewer.addFilter(new MyFilter());
好了,看一下效果

二、如果我们想凸显某一条记录,想改变一下它的颜色,如果实现呢,简单,只要几句话就可以了。

Color color = Display.getDefault().getSystemColor(SWT.COLOR_RED);
table.getItems()[table.getItemCount()-1].setBackground(color);
table.redraw();


三、这里提一下,使用tabeViewer.setUseHashlookup(true)可以在tableviewer内部为数据记录和tableItem之间的映射创建一个hash表,这样可以加快tableItem的和记录间的查找速度,注意,这条语句必须在setInput之前加入才有效。

好了,到此tableviewer的基本的东西介绍的差不多了

source下载:http://www.blogjava.net/Files/dreamstone/jface-4.rar

四:在现实的开发中,我们更多的是喜欢把一些简单的类用匿名类或者内部类的方式来实现。像之前例子中每个都单独一个类的情况并不多。

下边是和前边的source效果等同的source,不过是使用了匿名类和内部类。

http://www.blogjava.net/Files/dreamstone/jface-5.rar

参考:http://www.blogjava.net/dreamstone/archive/2007/11/12/134495.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: