zoukankan      html  css  js  c++  java
  • 关于SWT中的表格(TableViewer类)

    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 多了一个右键菜单的功能.

      

  • 相关阅读:
    unigui1404在delphi10.2.2安装
    入库单的一些业务逻辑
    mormot日志
    论MORMOT序列的JSON格式
    线程安全的队列
    SynDBOracle.pas
    轻量级的REST中间件
    TQuery
    100亿数据1万属性数据架构设计
    愤怒的TryCatch
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/4164671.html
Copyright © 2011-2022 走看看