關於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 多了一個右鍵菜單的功能.

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM