JFace是SWT的扩展.它提供了一组功能强大的界面组件.其中包含表格,树,列表.对话框,向导对话框等.
表格是一种在软件系统中很常用的数据表现形式.特别是基于数据库的应用系统.表格更是不可缺少的界面组件.
SWT的表格组件(Table类)还是不怎么使用的,开发中一般还是使用JFace的表格组件TableViewer.
TableViewer是在SWT的Table类的基础上扩展而来的.但是Table类并非TableViewer的父类.从下面的这两个类的继承图就可以看出来
这两个类甚至都不是同一个族系.
附上两个类的继承关系图:
Table类的 和TableViewer的
从下面的TableViewer类源代码可以看到,TableViewer把Table作为一个实例变量.
从而实现了对Table类的功能的扩展.
让数据在TableViewer中显示出来:
实体类的数据模型介绍:
以往的像ASP和PHP这类面向过程的编程模式,是从数据库中读取数据,也不用对数据做任何封装,直接将数据一条条的显示在表格中.
现在用Java这种面向对象的编程语言.我们应该用更规范的方式来操作数据.把数据库中的记录当做一个数据对象.
用一个类来表示.数据表的字段写成类的实例变量,这样的类在Java中叫做实体类.EJB的操作方式就是这样的.Hibernate也是这样.
数据库和表格之间加上了实体类.这样以往的"数据表→表格显示"变成了"数据库→实体类→表格显示"这样不是麻烦而是有很多好处:
1.表格显示的代码不再和数据库相关.例如将数据库由Oracle移植到MySQL时就不需要更改"数据库→实体类"这个环节的代码.
2.零散的字段变量统一在一个类中,程序代码结构紧凑,清晰,有利于今后代码段的维护,不要先看维护问题,很多系统做好后不敢再改,害怕改动后会牵扯到其他的地方,其中原因之一就是代码的结构太乱,编程不规范所致.
3.将数据封装在一个实体类中,在数据传递时也方便多了,可以将实体类作为一个参数在方法与方法之间来回传递.
数据在表格中的显示
在得到由List装载的包含数据信息的实体类对象后,接下来就是使用TableViewer来系那是这些数据,是吸纳过程一般要经过如下步骤:
1.定义一个TableViewer的式样,在定义之时,可以通过TableViewer构造函数提供的参数设置TableViewer的式样,这和SWT中式样的用法是一样的.
2.将TableViewer置于容器类中,并对其布局.这和其他的SWT组件是一样的.
3.创建TableViewer中的列(TableColumn)
4.用setInput方法输入数据.setInput就像人的嘴巴.TableViewer的数据由setInput方法输入.
5.设定内容器
6.设定标签器.
这个地方出现了两个新概念:内容器和标签器.这是两个重要的概念.在后面的JFace组件经常用到.
它们实际是IStructuredContentProvider,ITableLabelProvider这两个接口的实现类.
它们的作用就是定义数据自Input进入后应该如何在TableViewer中显示.因此这两个类是非常关键的.
表格TableViewer表格类是JFace组件中重要且典型的一个组件,其中涉及了JFace中的众多的重要的概念:内容器,便签器,过滤器,排序器和修改器,这些概念对后面的JFace组件特别是TreeViewer的学习非常重要.之后也可以体会到JFace非常突出的面向对象的特性.
JFace是SWT的扩展,它提供了一组功能强大的界面组件,其中包含表格,树,列表,对话框,向导对话框等.
表格是一种在软件系统中很常见的数据表现形式,特别是基于数据库的应用系统,表格更是不可缺少的界面组件,SWT的表格组件(Table类)前面已经介绍过了,但在实际项目开发中一般还是用JFace的表格组件TableViewer比较多,TableViewer组件是在SWT的Table组件基础上采用MVC模式扩展而来的.但Table并非TableViewer的父类,
不和数据库连接,自己建立一个实体类
People.java
1 /** 2 * 本类包含四个不同数据类型的变量,分别对应数据库中的四个字段。 3 * 这些变量设置成private类型的,外界通过setter和getter方法访问. 4 */ 5 public class People { 6 //这个地方id用的是包装类型Long,最好不要用int,因为Long类型默认是null,int默认是0, 7 //方便区别数据库中到底是0还是空. 8 private Long id; // 唯一识别码,在数据库里常为自动递增的ID列 9 private String name; // 姓名 10 private boolean sex; //true是男,flase是女 11 private int age; // 年龄 12 private Date createDate; //这个地方Date声明称Long类型也可以.(1970年到现在的毫秒数) 13 14 public Long getId() { 15 return id; 16 } 17 public void setId(Long id) { 18 this.id = id; 19 } 20 public int getAge() { 21 return age; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 } 26 public boolean isSex() { 27 return sex; 28 } 29 public void setSex(boolean sex) { 30 this.sex = sex; 31 } 32 public String getName() { 33 return name; 34 } 35 public void setName(String name) { 36 this.name = name; 37 } 38 public Date getCreateDate() { 39 return createDate; 40 } 41 public void setCreateDate(Date createDate) { 42 this.createDate = createDate; 43 } 44 }
数据的生成
由于数据操作是分两步走:"数据库---->实体类---->表格显示",实体类隔离了代码对数据库的依赖,所以,"数据库---->实体类"这一步就不讲了,这部分的代码于JFace组件的使用无关紧要,也不会影响表格组件的讲解.关于数据库方面,在后面的"插件项目实战"中会 有详细的示例.
由于没有了"数据库--->实体类"这一步了,那就实体类的对象如何生成呢?因为数据记录和实体对象相对应,新创建的实体对象就相当于一个空记录了,我们可以用其set方法一个个的将值投入实体对象中,这样就能得到带有数据的实体对象了.
为了今后便于扩展 ,将创建实体对象的方法集中在一个类中,这种专门负责创建对象的类又叫对象工厂.代码如下.
生产People对象的PeopleFactory.java
1 public class PeopleFactory { 2 3 /** 4 * PeopleFactory这个类用于生成People类的对象. 5 * 在项目和应用中,这些个People类的对象都对应着数据库中People表中的一条记录. 6 * 手动封装的People对象,放入到一个List集合中. 7 */ 8 public static List<People> getPeoples() { 9 //声明一个list对象来放People类的对象 10 List<People> list = new ArrayList<People>(); 11 // 第1个实体类对象 12 People people1 = new People(); 13 people1.setId(new Long(1)); 14 people1.setName("张三"); 15 people1.setSex(true);//男 16 people1.setAge(28); 17 people1.setCreateDate(new Date()); // 当前日期 18 list.add(people1); 19 20 // 第2个实体类对象 21 People people2 = new People(); 22 people2.setId(new Long(2)); 23 people2.setName("李四"); 24 people2.setSex(false); 25 people2.setAge(18); 26 people2.setCreateDate(new Date()); 27 list.add(people2); 28 29 // 第3个实体类对象 30 People people3 = new People(); 31 people3.setId(new Long(3)); 32 people3.setName("王五"); 33 people3.setSex(true); 34 people3.setAge(27); 35 people3.setCreateDate(new Date()); 36 list.add(people3); 37 38 return list; 39 } 40 }
1.在实际应用中,getPeoples()方法的代码可以从数据库中取数据的代码来替代.
2.这里的List不是SWT组件的List,而是Java基础类中的java.util.List,它是属于Java的集合类(Collection),List不是必须的,根据实际开发情况也可以用数组或其他集合来代替,如Set,Map等,Java一般都用集合Collection类存放数据.
数据在表格中的显示.
在得到由List装载的包含数据信息的实体类对象后,接下来就是使用TableViewer来显示这些数据,实现过程一般需要经过如下步骤:
1.定义一个TableViewer对象.在定义的时候,可以通过TableViewer构造函数提供的参数设置TableViewer的式样,这和SWT中式样的用法是一样的.
2.将TableViewer置于容器类中,并对其布局,这和其他的SWT组件是一样的.
3.创建TableViewer中的列(TableColumn)
4.用setInput方法输入数据,setInput就像人的嘴巴,TableViewer的数据由setInput方法输入.
5.设定内容器
6.设定标签器.
这里出现了两个新概念:内容器,标签器.这是两个重要的概念,在后面的JFace组件中会经常用到.
他们实际是IStructuredContentProvider,ITableProvider这两个接口的实现类.
它们的作用就是定义数据自Input进入后应该如何在TableViewer中显示,因此这两个类是很关键的.
整个的过程的流程图如下:
一般来说,创建界面的代码都是很长的,为了阅读上的方便,可以将界面生成代码分解成一个个的自定义的方法,同时将内容器和标签器也各写成一个单独的类.
TableViewerContentProvider.java
1 /** 2 * 创建这个类,主要是对List集合中的数据记录进行筛选和转化. 3 * 是"内容器"的作用. 4 * 内容器中主要是对setInput()输入的数据集集合(本例子中指的是在PeopleFactory中封装好的List集合)做处理. 5 * 并且转换化成一个数组返回. 6 * 7 * 实现对应的接口IStructuredContentProvider,然后实现其中的方法. 8 * @author kongxiaohan 9 */ 10 public class TableViewerContentProvider implements IStructuredContentProvider { 11 12 @Override 13 public void dispose() { 14 15 } 16 17 @Override 18 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 19 20 } 21 22 //实现IStructuredContentProvider接口之后,主要复写的就是这个getElements()方法. 23 @Override 24 public Object[] getElements(Object inputElement) {//setInput传过来的是一个集合 25 if(inputElement instanceof List){//对这个参数进行类型的判断. 26 return ((List)inputElement).toArray();//将setInput传过来的List变成一个数组输出 27 }else{ 28 return new Object[0]; 29 } 30 } 31 }
TableViewerLabelProvider.java
1 /** 2 * 这个方法主要是作为"标签器"的作用来用的. 3 * "标签器"将一个个实体对象的字段变量分别取出然后系那是在TableViewer的各个列中. 4 * 实现对应的接口 5 * @author kongxiaohan 6 */ 7 public class TableViewerLabelProvider implements ITableLabelProvider{ 8 @Override 9 public Image getColumnImage(Object element, int columnIndex) { 10 return null;//这个和getColumnText()不同的是,这个方法可以返回一个null值. 11 } 12 13 /** 14 * 由此方法决定数据记录在表格的每一列是显示什么文字 15 * @param element 实体类对象 16 * @param columnIndex 列号,0是第一列 17 * @return 返回值一定要避免NULL值,否则出错 18 */ 19 @Override 20 public String getColumnText(Object element, int columnIndex) { 21 People people = (People) element; 22 if(columnIndex == 0){ 23 return people.getId().toString(); 24 } 25 26 if(columnIndex == 1){ 27 return people.getName(); 28 } 29 30 if(columnIndex == 2){ 31 return people.isSex() ? "男" : "女"; 32 } 33 34 if(columnIndex == 3){ 35 return people.getAge() + ""; 36 //这个地方是boolen类型的set和getter方法特别的地方.是"is"开头的 37 } 38 39 if(columnIndex == 4){ 40 return people.getCreateDate().toString(); 41 } 42 //当都不符合的时候返回一个空字符串 43 return ""; 44 } 45 46 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>书上说以下这几个方法用处不大,空实现就可以了>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 47 @Override 48 public void addListener(ILabelProviderListener listener) { 49 50 } 51 52 @Override 53 public void dispose() { 54 55 } 56 57 @Override 58 public boolean isLabelProperty(Object element, String property) { 59 return false; 60 } 61 62 @Override 63 public void removeListener(ILabelProviderListener listener) { 64 65 } 66 }
右键菜单的MyActionGroup.java
1 //继承ActionGroup 2 public class MyActionGroup extends ActionGroup{ 3 private TableViewer tableViewer; 4 5 /** 6 * 鼠标右键有菜单,首先要 7 * 生成菜单Menu,并将两个Action传入 8 */ 9 public void fillContextMenu(IMenuManager mgr){//I开头的一般是接口的意思. 10 //加入两个Action对象到菜单管理器中 11 MenuManager menuManager = (MenuManager) mgr; //因为传入的是一个接口,所以这个地方要转换一下类名. 12 menuManager.add(new OpenAction()); 13 menuManager.add(new RefreshAction()); 14 15 /* 16 * 这一段代码是什么意思..........????????有点搞不懂. 17 */ 18 //生成Menu并挂载表格table上,menu和table两个对象互为对方的参数. 19 Table table = tableViewer.getTable(); 20 Menu menu = menuManager.createContextMenu(table); 21 table.setMenu(menu); 22 23 } 24 25 /** 26 * 用来接受TableViewer对象的构造函数。 27 * 因为在Action会要使用到TableViewer对象 所以一定要把TableViewer传进来。 28 */ 29 public MyActionGroup(TableViewer tableViewer) { 30 this.tableViewer = tableViewer; 31 } 32 33 /** 34 * "打开"的Action类 35 */ 36 private class OpenAction extends Action{ 37 public OpenAction(){ 38 setText("打开"); 39 } 40 /** 41 * 继承自Action的方法,动作代码写在此方法中. 42 */ 43 public void run(){ 44 IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection(); 45 People obj = (People) (selection.getFirstElement()); 46 if (obj == null) { 47 MessageDialog.openInformation(null, null, "选选择记录"); 48 } else { 49 MessageDialog.openInformation(null, null, obj.getName()); 50 } 51 } 52 } 53 54 /** 55 * 刷新的Action类 56 */ 57 private final class RefreshAction extends Action{ 58 public RefreshAction(){ 59 setText("刷新"); 60 } 61 62 public void run(){ 63 tableViewer.refresh();//调用表格的刷新方法. 64 } 65 } 66 }
三个TableViewer的实体类
TableViewer1.java
1 /** 2 * TableViewer类的实现类 3 * @author kongxiaohan 4 */ 5 public class TableViewer1 { 6 //首先定义一个表格(TableViewer类)对象 7 private TableViewer tableviewer; 8 9 public static void main(String[] args) { 10 TableViewer1 window = new TableViewer1(); 11 window.open(); 12 } 13 14 //定义这个open()方法.就是创建一个典型的SWT程序的步骤 15 public void open(){ 16 //1.display负责管理一实现循环和控制UI线程和其他线程之间的通信 17 Display display = new Display(); 18 //2.创建一个或者多个Shell(shell是程序的主窗口) 19 Shell shell = new Shell(); 20 //3.设置shell的布局. 21 shell.setSize(500, 150); 22 //设置shell的布局为FillLayout 23 shell.setLayout(new FillLayout()); 24 shell.setText("TableViewer的第一个例子"); 25 //调用自定义的方法创建表格 26 createTableViewer(shell); 27 //4.设定内容器 28 tableviewer.setContentProvider(new TableViewerContentProvider()); 29 //5.设定标签器 30 tableviewer.setLabelProvider(new TableViewerLabelProvider()); 31 //6.用setInput输入数据(把PeopleFactory产生的List集合传进来) 32 tableviewer.setInput(PeopleFactory.getPeoples()); 33 34 //7.创建Shell中的组件(这个例子中没有加入组件,只有一个空窗口) 35 shell.open(); 36 //8.写一个时间转发循环 37 while(!shell.isDisposed()){//如果主窗口没有关闭,则一直循环 38 //dispose 是"处理,处置,毁掉"的意思 39 if(!display.readAndDispatch()){//// 如果display不忙 40 display.sleep();// display休眠 41 } 42 } 43 } 44 45 46 /** 47 * 创建一个表格 48 */ 49 public void createTableViewer(Composite prarent){ 50 /** 51 * 第一步:定义一个TableViewer对象. 52 * 同时在构造方法中定义其式样. 这里设置成可以多选(SWT.MULTI), 53 * 有水平滚动条(SWT.H_SCROLL),有垂直滚动条(SWT.V_SCROLL), 54 * 有边框(SWT.BORDER),可以整行选择(SWT.FULL_SELECTION) 55 */ 56 tableviewer = new TableViewer(prarent, SWT.MULTI | SWT.H_SCROLL 57 | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.FULL_SELECTION ); 58 59 /** 60 * 第二步:通过TableViewer中的Table对其布局. 61 */ 62 Table table = tableviewer.getTable(); 63 table.setHeaderVisible(true);//设置标头 64 table.setLinesVisible(true);//显示表格线 65 TableLayout tLayout = new TableLayout();//专用于表格的布局 66 table.setLayout(tLayout); 67 68 /** 69 * 第三步:建立TableViewer中的列 70 */ 71 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 72 new TableColumn(table, SWT.NONE).setText("ID号"); 73 74 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为40像素 75 new TableColumn(table, SWT.NONE).setText("姓名"); 76 77 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 78 new TableColumn(table, SWT.NONE).setText("性别"); 79 80 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 81 new TableColumn(table, SWT.NONE).setText("年龄"); 82 83 tLayout.addColumnData(new ColumnWeightData(70));//这个是设置ID列的列宽为70像素 84 new TableColumn(table, SWT.NONE).setText("记录建立时间"); 85 } 86 }
程序说明:
TableViewer的setInput方法的参数类型是Object,所以它可以接受任何类型的参数,SWT/JFace中很多参数都是这样的,所以参数对象进入到方法内部后要机型类型和转换,这是个比较麻烦的一件事,因此在内容器里要将参数转换过来,如(List)element.但如果某种情况下element参数不是List类型,程序就会报错,所以最好用element instanceof List来做一下类型判断比较稳妥,在SWT/JFace编程中很多的BUG都出现在这种地方.
还有一个出BUG比较多的是空值(null)的判断,实践经验表明,50%以上的BUG都出在空值异常上,像内容器的getColumnImage方法能返回null值,但getColumnText返回null值就会出错,所以为了程序的稳定和健壮,对方法的参数做一下空值判断是非常有必要的,除非你确定该值不可能为空值.
TableViewer.java的运行结果:
TableViewer2.java
1 /** 2 * 这个例子比TableViewer1多了一个双击一条记录会弹出一个含有姓名的对话框 3 * 仅仅是多了一个这样的事件. 4 * @author kongxiaohan 5 */ 6 public class TableViewer2 { 7 //首先定义一个表格(TableViewer类)对象 8 private TableViewer tableViewer; 9 10 public static void main(String[] args) { 11 TableViewer2 window = new TableViewer2(); 12 //因为这类和TableViewer1的代码基本上是一样的,我就原样拷贝过TableViewer1的代码来了 13 //但是这个地方应该改成TableViewer2的. 14 window.open(); 15 } 16 17 //定义这个open()方法.就是创建一个典型的SWT程序的步骤 18 public void open(){ 19 //1.display负责管理一实现循环和控制UI线程和其他线程之间的通信 20 Display display = new Display(); 21 //2.创建一个或者多个Shell(shell是程序的主窗口) 22 Shell shell = new Shell(); 23 //3.设置shell的布局. 24 shell.setSize(500, 150); 25 //设置shell的布局为FillLayout 26 shell.setLayout(new FillLayout()); 27 shell.setText("TableViewer的第二个例子"); 28 //调用自定义的方法创建表格 29 createTableViewer(shell); 30 //4.设定内容器 31 tableViewer.setContentProvider(new TableViewerContentProvider()); 32 //5.设定标签器 33 tableViewer.setLabelProvider(new TableViewerLabelProvider()); 34 //6.用setInput输入数据(把PeopleFactory产生的List集合传进来) 35 tableViewer.setInput(PeopleFactory.getPeoples()); 36 37 //>>>>>>>>>>>>>>>>相比于TableViewer1.java中新增加的>>>>>>>>>>>>>>>>> 38 //增加一个监听器 39 addListener(); 40 41 42 //7.创建Shell中的组件(这个例子中没有加入组件,只有一个空窗口) 43 shell.open(); 44 //8.写一个时间转发循环 45 while(!shell.isDisposed()){//如果主窗口没有关闭,则一直循环 46 //dispose 是"处理,处置,毁掉"的意思 47 if(!display.readAndDispatch()){//// 如果display不忙 48 display.sleep();// display休眠 49 } 50 } 51 } 52 53 54 /** 55 * 创建一个表格 56 */ 57 public void createTableViewer(Composite prarent){ 58 /** 59 * 第一步:定义一个TableViewer对象. 60 * 同时在构造方法中定义其式样. 这里设置成可以多选(SWT.MULTI), 61 * 有水平滚动条(SWT.H_SCROLL),有垂直滚动条(SWT.V_SCROLL), 62 * 有边框(SWT.BORDER),可以整行选择(SWT.FULL_SELECTION) 63 */ 64 tableViewer = new TableViewer(prarent, SWT.MULTI | SWT.H_SCROLL 65 | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.FULL_SELECTION ); 66 67 /** 68 * 第二步:通过TableViewer中的Table对其布局. 69 */ 70 Table table = tableViewer.getTable(); 71 table.setHeaderVisible(true);//设置标头 72 table.setLinesVisible(true);//显示表格线 73 TableLayout tLayout = new TableLayout();//专用于表格的布局 74 table.setLayout(tLayout); 75 76 /** 77 * 第三步:建立TableViewer中的列 78 */ 79 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 80 new TableColumn(table, SWT.NONE).setText("ID号"); 81 82 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为40像素 83 new TableColumn(table, SWT.NONE).setText("姓名"); 84 85 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 86 new TableColumn(table, SWT.NONE).setText("性别"); 87 88 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 89 new TableColumn(table, SWT.NONE).setText("年龄"); 90 91 tLayout.addColumnData(new ColumnWeightData(70));//这个是设置ID列的列宽为70像素 92 new TableColumn(table, SWT.NONE).setText("记录建立时间"); 93 } 94 95 /** 96 * 新增加的监听器 97 */ 98 public void addListener(){ 99 //TableViewer的双击事件的监听 100 tableViewer.addDoubleClickListener(new IDoubleClickListener() {//IDoubleClickListener是一个接口 101 @Override 102 public void doubleClick(DoubleClickEvent event) { 103 IStructuredSelection selection = (IStructuredSelection) event.getSelection(); 104 //得到记录的实体对象(要类型转换) 105 People people = (People) selection.getFirstElement(); 106 //一个弹出提示框 107 MessageDialog.openInformation(null, "提示", people.getName()); 108 } 109 }); 110 111 /* 112 * tv的选择事件(单击)监听 113 */ 114 tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { 115 @Override 116 public void selectionChanged(SelectionChangedEvent event) { 117 // 如果要定义单击的事件的处理在这里写代码....... 118 } 119 }); 120 } 121 }
TableViewer2.java的运行结果.
相比TableViewer1.java 多了一个双击记录弹出名字的功能.
TableView3.java
1 /** 2 * 这个例子在TableViewer2的基础上增加了右键的菜单 3 * @author kongxiaohan 4 */ 5 public class TableViewer3 { 6 //首先定义一个表格(TableViewer类)对象 7 private TableViewer tableViewer; 8 9 public static void main(String[] args) { 10 TableViewer3 window = new TableViewer3(); 11 //因为这类和TableViewer1的代码基本上是一样的,我就原样拷贝过TableViewer1的代码来了 12 //但是这个地方应该改成TableViewer2的. 13 window.open(); 14 } 15 16 //定义这个open()方法.就是创建一个典型的SWT程序的步骤 17 public void open(){ 18 //1.display负责管理一实现循环和控制UI线程和其他线程之间的通信 19 Display display = new Display(); 20 //2.创建一个或者多个Shell(shell是程序的主窗口) 21 Shell shell = new Shell(); 22 //3.设置shell的布局. 23 shell.setSize(500, 150); 24 //设置shell的布局为FillLayout 25 shell.setLayout(new FillLayout()); 26 shell.setText("TableViewer的第三个例子"); 27 //调用自定义的方法创建表格 28 createTableViewer(shell); 29 //4.设定内容器 30 tableViewer.setContentProvider(new TableViewerContentProvider()); 31 //5.设定标签器 32 tableViewer.setLabelProvider(new TableViewerLabelProvider()); 33 //6.用setInput输入数据(把PeopleFactory产生的List集合传进来) 34 tableViewer.setInput(PeopleFactory.getPeoples()); 35 36 //>>>>>>>>>>>>>>>>相比于TableViewer1.java中新增加的>>>>>>>>>>>>>>>>> 37 //增加一个监听器 38 addListener(); 39 //>>>>>>>>>>>>>>>>相比于TableViewer2.java中新增加的>>>>>>>>>>>>>>>>> 40 //生成一个ActionGroup对象. 41 MyActionGroup actionGroup = new MyActionGroup(tableViewer); 42 // 调用fillContextMenu方法将按钮注入到菜单对象中 43 actionGroup.fillContextMenu(new MenuManager()); 44 45 46 47 //7.创建Shell中的组件(这个例子中没有加入组件,只有一个空窗口) 48 shell.open(); 49 //8.写一个时间转发循环 50 while(!shell.isDisposed()){//如果主窗口没有关闭,则一直循环 51 //dispose 是"处理,处置,毁掉"的意思 52 if(!display.readAndDispatch()){//// 如果display不忙 53 display.sleep();// display休眠 54 } 55 } 56 } 57 58 59 /** 60 * 创建一个表格 61 */ 62 public void createTableViewer(Composite prarent){ 63 /** 64 * 第一步:定义一个TableViewer对象. 65 * 同时在构造方法中定义其式样. 这里设置成可以多选(SWT.MULTI), 66 * 有水平滚动条(SWT.H_SCROLL),有垂直滚动条(SWT.V_SCROLL), 67 * 有边框(SWT.BORDER),可以整行选择(SWT.FULL_SELECTION) 68 */ 69 tableViewer = new TableViewer(prarent, SWT.MULTI | SWT.H_SCROLL 70 | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.FULL_SELECTION ); 71 72 /** 73 * 第二步:通过TableViewer中的Table对其布局. 74 */ 75 Table table = tableViewer.getTable(); 76 table.setHeaderVisible(true);//设置标头 77 table.setLinesVisible(true);//显示表格线 78 TableLayout tLayout = new TableLayout();//专用于表格的布局 79 table.setLayout(tLayout); 80 81 /** 82 * 第三步:建立TableViewer中的列 83 */ 84 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 85 new TableColumn(table, SWT.NONE).setText("ID号"); 86 87 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为40像素 88 new TableColumn(table, SWT.NONE).setText("姓名"); 89 90 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 91 new TableColumn(table, SWT.NONE).setText("性别"); 92 93 tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素 94 new TableColumn(table, SWT.NONE).setText("年龄"); 95 96 tLayout.addColumnData(new ColumnWeightData(70));//这个是设置ID列的列宽为70像素 97 new TableColumn(table, SWT.NONE).setText("记录建立时间"); 98 } 99 100 /** 101 * 新增加的监听器 102 */ 103 public void addListener(){ 104 //TableViewer的双击事件的监听 105 tableViewer.addDoubleClickListener(new IDoubleClickListener() {//IDoubleClickListener是一个接口 106 @Override 107 public void doubleClick(DoubleClickEvent event) { 108 IStructuredSelection selection = (IStructuredSelection) event.getSelection(); 109 //得到记录的实体对象(要类型转换) 110 People people = (People) selection.getFirstElement(); 111 //一个弹出提示框 112 MessageDialog.openInformation(null, "提示", people.getName()); 113 } 114 }); 115 116 /* 117 * tv的选择事件(单击)监听 118 */ 119 tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { 120 @Override 121 public void selectionChanged(SelectionChangedEvent event) { 122 // 如果要定义单击的事件的处理在这里写代码....... 123 } 124 }); 125 } 126 }
TableViewer3.java的运行结果是:
相比TableViewer2.java 多了一个右键菜单的功能.