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. public void createTableViewer(Composite prarent){
  49. /**
  50. * 第一步:定义一个TableViewer对象.
  51. * 同时在构造方法中定义其式样. 这里设置成可以多选(SWT.MULTI),
  52. * 有水平滚动条(SWT.H_SCROLL),有垂直滚动条(SWT.V_SCROLL),
  53. * 有边框(SWT.BORDER),可以整行选择(SWT.FULL_SELECTION)
  54. */
  55. tableviewer = new TableViewer(prarent, SWT.MULTI | SWT.H_SCROLL
  56. | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.FULL_SELECTION );
  57.  
  58. /**
  59. * 第二步:通过TableViewer中的Table对其布局.
  60. */
  61. Table table = tableviewer.getTable();
  62. table.setHeaderVisible(true);//设置标头
  63. table.setLinesVisible(true);//显示表格线
  64. TableLayout tLayout = new TableLayout();//专用于表格的布局
  65. table.setLayout(tLayout);
  66.  
  67. /**
  68. * 第三步:建立TableViewer中的列
  69. */
  70. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  71. new TableColumn(table, SWT.NONE).setText("ID号");
  72.  
  73. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为40像素
  74. new TableColumn(table, SWT.NONE).setText("姓名");
  75.  
  76. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  77. new TableColumn(table, SWT.NONE).setText("性别");
  78.  
  79. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  80. new TableColumn(table, SWT.NONE).setText("年龄");
  81.  
  82. tLayout.addColumnData(new ColumnWeightData(70));//这个是设置ID列的列宽为70像素
  83. new TableColumn(table, SWT.NONE).setText("记录建立时间");
  84. }
  85. }

程序说明:

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. //7.创建Shell中的组件(这个例子中没有加入组件,只有一个空窗口)
  42. shell.open();
  43. //8.写一个时间转发循环
  44. while(!shell.isDisposed()){//如果主窗口没有关闭,则一直循环
  45. //dispose 是"处理,处置,毁掉"的意思
  46. if(!display.readAndDispatch()){//// 如果display不忙
  47. display.sleep();// display休眠
  48. }
  49. }
  50. }
  51.  
  52. /**
  53. * 创建一个表格
  54. */
  55. public void createTableViewer(Composite prarent){
  56. /**
  57. * 第一步:定义一个TableViewer对象.
  58. * 同时在构造方法中定义其式样. 这里设置成可以多选(SWT.MULTI),
  59. * 有水平滚动条(SWT.H_SCROLL),有垂直滚动条(SWT.V_SCROLL),
  60. * 有边框(SWT.BORDER),可以整行选择(SWT.FULL_SELECTION)
  61. */
  62. tableViewer = new TableViewer(prarent, SWT.MULTI | SWT.H_SCROLL
  63. | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.FULL_SELECTION );
  64.  
  65. /**
  66. * 第二步:通过TableViewer中的Table对其布局.
  67. */
  68. Table table = tableViewer.getTable();
  69. table.setHeaderVisible(true);//设置标头
  70. table.setLinesVisible(true);//显示表格线
  71. TableLayout tLayout = new TableLayout();//专用于表格的布局
  72. table.setLayout(tLayout);
  73.  
  74. /**
  75. * 第三步:建立TableViewer中的列
  76. */
  77. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  78. new TableColumn(table, SWT.NONE).setText("ID号");
  79.  
  80. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为40像素
  81. new TableColumn(table, SWT.NONE).setText("姓名");
  82.  
  83. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  84. new TableColumn(table, SWT.NONE).setText("性别");
  85.  
  86. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  87. new TableColumn(table, SWT.NONE).setText("年龄");
  88.  
  89. tLayout.addColumnData(new ColumnWeightData(70));//这个是设置ID列的列宽为70像素
  90. new TableColumn(table, SWT.NONE).setText("记录建立时间");
  91. }
  92.  
  93. /**
  94. * 新增加的监听器
  95. */
  96. public void addListener(){
  97. //TableViewer的双击事件的监听
  98. tableViewer.addDoubleClickListener(new IDoubleClickListener() {//IDoubleClickListener是一个接口
  99. @Override
  100. public void doubleClick(DoubleClickEvent event) {
  101. IStructuredSelection selection = (IStructuredSelection) event.getSelection();
  102. //得到记录的实体对象(要类型转换)
  103. People people = (People) selection.getFirstElement();
  104. //一个弹出提示框
  105. MessageDialog.openInformation(null, "提示", people.getName());
  106. }
  107. });
  108.  
  109. /*
  110. * tv的选择事件(单击)监听
  111. */
  112. tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
  113. @Override
  114. public void selectionChanged(SelectionChangedEvent event) {
  115. // 如果要定义单击的事件的处理在这里写代码.......
  116. }
  117. });
  118. }
  119. }

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. //7.创建Shell中的组件(这个例子中没有加入组件,只有一个空窗口)
  46. shell.open();
  47. //8.写一个时间转发循环
  48. while(!shell.isDisposed()){//如果主窗口没有关闭,则一直循环
  49. //dispose 是"处理,处置,毁掉"的意思
  50. if(!display.readAndDispatch()){//// 如果display不忙
  51. display.sleep();// display休眠
  52. }
  53. }
  54. }
  55.  
  56. /**
  57. * 创建一个表格
  58. */
  59. public void createTableViewer(Composite prarent){
  60. /**
  61. * 第一步:定义一个TableViewer对象.
  62. * 同时在构造方法中定义其式样. 这里设置成可以多选(SWT.MULTI),
  63. * 有水平滚动条(SWT.H_SCROLL),有垂直滚动条(SWT.V_SCROLL),
  64. * 有边框(SWT.BORDER),可以整行选择(SWT.FULL_SELECTION)
  65. */
  66. tableViewer = new TableViewer(prarent, SWT.MULTI | SWT.H_SCROLL
  67. | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.FULL_SELECTION );
  68.  
  69. /**
  70. * 第二步:通过TableViewer中的Table对其布局.
  71. */
  72. Table table = tableViewer.getTable();
  73. table.setHeaderVisible(true);//设置标头
  74. table.setLinesVisible(true);//显示表格线
  75. TableLayout tLayout = new TableLayout();//专用于表格的布局
  76. table.setLayout(tLayout);
  77.  
  78. /**
  79. * 第三步:建立TableViewer中的列
  80. */
  81. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  82. new TableColumn(table, SWT.NONE).setText("ID号");
  83.  
  84. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为40像素
  85. new TableColumn(table, SWT.NONE).setText("姓名");
  86.  
  87. tLayout.addColumnData(new ColumnWeightData(20));//这个是设置ID列的列宽为10像素
  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(70));//这个是设置ID列的列宽为70像素
  94. new TableColumn(table, SWT.NONE).setText("记录建立时间");
  95. }
  96.  
  97. /**
  98. * 新增加的监听器
  99. */
  100. public void addListener(){
  101. //TableViewer的双击事件的监听
  102. tableViewer.addDoubleClickListener(new IDoubleClickListener() {//IDoubleClickListener是一个接口
  103. @Override
  104. public void doubleClick(DoubleClickEvent event) {
  105. IStructuredSelection selection = (IStructuredSelection) event.getSelection();
  106. //得到记录的实体对象(要类型转换)
  107. People people = (People) selection.getFirstElement();
  108. //一个弹出提示框
  109. MessageDialog.openInformation(null, "提示", people.getName());
  110. }
  111. });
  112.  
  113. /*
  114. * tv的选择事件(单击)监听
  115. */
  116. tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
  117. @Override
  118. public void selectionChanged(SelectionChangedEvent event) {
  119. // 如果要定义单击的事件的处理在这里写代码.......
  120. }
  121. });
  122. }
  123. }

TableViewer3.java的运行结果是:

相比TableViewer2.java 多了一个右键菜单的功能.

  

关于SWT中的表格(TableViewer类)的更多相关文章

  1. 关于SWT中的Label类和Text类

    Label类的继承关系图 Label是SWT中最简单的界面组件,给出他的一个实例如下: public class Label1 { public static void main(String[] a ...

  2. SWT中各种参数大全

    1按钮组件(Button) (1)Button组件常用样式 SWT.PUSH按钮 SWT.CHECK多选按钮 SWT.RADIO单选按钮 SWT.ARROW箭头按钮 SWT.NONE默认按钮 SWT. ...

  3. ASP.NET中重复表格列合并的实现方法(转自脚本之家)

    这几天做一个项目有用到表格显示数据的地方,客户要求重复的数据列需要合并,就总结了一下.NET控件GridView 和 Repeater 关于重复数据合并的方法. 这是合并之前的效果: 合并之后的效果图 ...

  4. C# 如何在PDF文档中创建表格

    表格能够直观的传达数据信息,使信息显得条理化,便于阅读同时也利于管理.那在PDF类型的文档中如何来添加表格并且对表格进行格式化操作呢?使用常规方法直接在PDF中添加表格行不通,那我们可以在借助第三方组 ...

  5. C# 在Word中添加表格的方法

    表格是组织整理数据的一种重要手段,应在生活中的方方面面.在Word文档中将繁杂的文字表述内容表格化,能快速.直接地获取关键内容信息.那么,通过C#,我们也可以在Word文档中添加表格,这里将介绍两种不 ...

  6. word模板导出的几种方式:第一种:占位符替换模板导出(只适用于word中含有表格形式的)

    1.占位符替换模板导出(只适用于word中含有表格形式的): /// <summary> /// 使用替换模板进行到处word文件 /// </summary> public ...

  7. python简单爬虫 用lxml解析页面中的表格

    目标:爬取湖南大学2018年在各省的录取分数线,存储在txt文件中 部分表格如图: 部分html代码: <table cellspacing="0" cellpadding= ...

  8. SWT中ole/activex实践--操作word的一个例子

    http://setting.iteye.com/blog/747295 ———————————————————————————————————————————————— 这几年,做了很多word/e ...

  9. [.NET开发] C# 如何在PDF文档中创建表格

    表格能够直观的传达数据信息,使信息显得条理化,便于阅读同时也利于管理.那在PDF类型的文档中如何来添加表格并且对表格进行格式化操作呢?使用常规方法直接在PDF中添加表格行不通,那我们可以在借助第三方组 ...

随机推荐

  1. 《转》高级Unix命令

    原文链接:http://coolshell.cn/articles/1044.html 在Unix操作中有太多太多的命令,这些命令的强大之处就是一个命令只干一件事,并把这件事干好.Do one thi ...

  2. 使用C语言实现二维,三维绘图算法(2)-解析曲面的显示

    使用C语言实现二维,三维绘图算法(2)-解析曲面的显示 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  3. Inf2Cat, signability test failed.

    驱动开发真不是那么好玩的,折腾了几天,排除了几个错误,又有新的错误了. 错误    1    error -2: "Inf2Cat, signability test failed.&quo ...

  4. TCP 滑动窗口的简介

    TCP 滑动窗口的简介 POSTED BY ADMIN ON AUG 1, 2012 IN FLOWS34ARTICLES | 0 COMMENTS TCP的滑动窗口主要有两个作用,一是提供TCP的可 ...

  5. 《Data-Intensive Text Processing with mapReduce》读书笔记之一:前言

    暑假闲得蛋痒,混混沌沌,开始看<Data-Intensive Text Processing with mapReduce>,尽管有诸多单词不懂,还好六级考多了,虽然至今未过:再加上自己当 ...

  6. hdu4812-D Tree (树的点分治)

    昨天学了下树分治,今天补这道题,还是太不熟练了,写完之后一直超时.后来查出好多错= =比如v,u写倒了,比如+写成了取最值,比如....爆int...查了两个多小时的错..哭...(没想到进首页了 h ...

  7. 新浪新闻API接口

    头条 http://api.sina.cn/sinago/list.json?channel=news_toutiao推荐 http://api.sina.cn/sinago/list.json?ch ...

  8. web.xml(spring/spring mvc/hibernate)

    <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" ...

  9. vs之Nuget

    1.http://msdn.microsoft.com/zh-cn/magazine/hh547106.aspx 2.在Nuget控制台中安装特定版本: Install-Package <程序包 ...

  10. position绝对剧中

    function loginH(){ var loginH = $('.sign-main-bg .sign-main-content'); var h = loginH.height(); logi ...