java基礎 ---JFace中的TableViewer

java基礎 ---JFace中的TableViewer

在上一篇介紹了SWT/JFace窗口的建立,以及窗口的一些屬性的設置。還有菜單欄的建立。下面介紹一下表格的建立。在SWT中有個Table類,用法也比較簡單。但是我們一般採用的是JFace中的TableViewer來建立一個表格。我們可以從API文檔中看到,SWT的Table和JFace的TableViewer並不是繼承關係,他們屬於兩條不同的繼承鏈。但是從TableViewer的源代碼中可以發現,TableViewer把Table作爲一個實例變量,也就是說TableViewer是對Table的一種擴展。關於數據傳輸類的建立這些就暫不做介紹了,我們直達正題,建立一個表格,並在其中顯示出數據。建立TableViewer需要幾個步驟,一般只要按照這個步驟來做Table,那就沒什麼大的問題了。
1、 建立TableViewer對象,定義Table的式樣,和SWT中其他的式樣用法是一樣的。
2、 將TableViewer置於容器中,並對其佈局,這個和其他SWT組件是一樣的。
3、 創建TableViewer中的標題,就是Header
4、 設置內容器
5、 設置標籤器
6、 用setInput方法將數據顯示在表格中。

經過上面6步,表格就基本上建立完成了。這裏要說明一下什麼是內容器和標籤器。Jface的TableViewer把寫入數據封裝成了2個接口,一個就是內容器接口IStructuredContentProvider,還有個就是標籤器接口ITableLabelProvider。我們需要實現這兩個接口的兩個方法才能將數據寫入到表格中。內容器是接收到1個Object對象,這個Object對象可以是容器類對象或者數組,然後返回一個一維Object數組。他的作用就是通過傳遞進來的參數來自動設置表格中的數據需要佔多少行。標籤器接口中的getColumnText方法參數是1個object對象和需要寫入數據的列數,返回一個String對象。他的作用相當於把每個字段的值寫入到表格中。當我們實現了這些方法後,這些方法該如何調用是不需要我們關心的,你只要保證傳進來的參數不會出現問題那就行了。我們只需要在程序中創建這兩個類的對象,然後將他們作爲TableViewer的setContentProvider()和setLabelProvider()這兩個方法的參數就行了,最後將要放入表格的集合類對象或者數組作爲setInput()的參數,表格的數據顯示就完成了。

SWT中的佈局管理器我這裏就不多講了,有興趣可以翻翻這方面的資料,比較的常用的還是GridLayout和FormLayout,這兩個佈局管理器是SWT中最複雜也是最強大的兩個佈局管理器,無論你是選擇這兩種中的哪一種,完全可以設計出任何複雜的界面。GridLayout是按行和列來排列組件的,他主要是用在窗體大小固定不變的時候,如果窗體大小會發生變化,那使用這個佈局管理器就顯得有點力不從心了。我還是比較傾向於使用FormLayout,因爲這個管理器是按位置的百分比來設置組件的位置,也可以相對於某個組件來排列,用它來管理佈局界面,可以讓我們的界面排列方式更加細緻。儘管他使用起來還要複雜點。下面將演示如何建立表格,並通過相應的按鈕向裏面一行一行的添加數據。還可以對錶格的所有數據進行清空以及顯示。雙擊表格中的數據時會彈出窗口顯示當前選中行的第0列字段的值。在大多數例子中都只演示瞭如何通過集合類,如List,Set,Map等將數據寫入到表格中,我這裏演示一下如將二維數組寫入表格中。

 將下面的代碼替換上篇文章中主窗口類的createContents方法,下面還有個監聽器的方法,寫在這個方法的下面也可以

protected Control createContents(Composite pare) {

    
// 獲得窗口的shell對象
    Shell shell = this.getShell();
    Toolkit kit 
= Toolkit.getDefaultToolkit();
    
// 設置窗口標題
    shell.setText("我的通訊錄-授權:Administrator");
    
// 設置窗口默認大小
    shell.setSize(700400);
    
// 將窗口居中
    shell.setLocation((kit.getScreenSize().width - 700/ 2, (kit
            .getScreenSize().height 
- 400/ 2);
    MenuManager popMenu 
= new MenuManager();
    popMenu.add(
new OpenFile());
    popMenu.add(
new SaveFile());
    Menu menu 
= popMenu.createContextMenu(pare);
    pare.setMenu(menu);
    
    
//創建FormLayout佈局管理器對象
    FormLayout form = new FormLayout();
    
//將pare容器按照FormLayout來佈局
    pare.setLayout(form);
    
//通過JFaceTable類的creatTableViewer()創建一個TableViewer對象
    final TableViewer tableViewer = new JFaceTable().creatTableViewer(pare);
    
//設置TableViewer內容器
    tableViewer.setContentProvider(new JFaceTable().new TableViewerContentProvider());
    
//設置TableViewer標籤器
    tableViewer.setLabelProvider(new JFaceTable().new TableViewerLabelProvider());
    
//增加表格中雙擊事件,可以獲得當前選擇行的第一列字段的值。
    tableViewer.addDoubleClickListener(new IDoubleClickListener(){
        
public void doubleClick(DoubleClickEvent e) {
            TableItem item 
= tableViewer.getTable().getItem(tableViewer.getTable().getSelectionIndex());
            MessageDialog.openInformation(
null,"提示",item.getText(0));
        }
    });
    
    
//創建FormLayout佈局管理器的佈局數據類對象
    FormData formData = new FormData();
    
//FormAttachment是FormData更進一步的佈局數據類
    
//該組件左邊距他父容器左邊距離的百分比。第二個參數是偏移量
    formData.left = new FormAttachment(05);
    
//該組件右邊距他父容器左邊距離的百分比
    
//這裏設置的時候左邊一定要比右邊的百分比小,否則組件就會看不見了。
    formData.right = new FormAttachment(100-5);
    
//該組件上邊距他父容器上面距離的百分比
    formData.top = new FormAttachment(05);
    
//該組件下邊距他父容器上面距離的百分比
    
//這裏設置的時候上邊一定要比下邊的百分比小,否則組件就會看不見了。
    formData.bottom = new FormAttachment(100-80);
    
//獲得tableViewer的Table對象
    
//因爲在TableViewer裏面包含有Table,所以我們依然可以在TableViewer
    
//上使用Table類的方法,不過要先獲得該TableViewer對象的table對象
    Table table = tableViewer.getTable();
    
//將這個佈局數據類應用於table
    table.setLayoutData(formData);
    
//建立一個帶有標題文字和邊框的容器
    Group group = new Group(pare, SWT.NONE);
    group.setText(
"控制區");
    formData 
= new FormData();
    formData.left 
= new FormAttachment(05);
    formData.right 
= new FormAttachment(100-5);
    formData.top 
= new FormAttachment(table, 5, SWT.BOTTOM);
    formData.bottom 
= new FormAttachment(100-5);
    group.setLayoutData(formData);

    GridLayout grid 
= new GridLayout();
    grid.numColumns 
= 2;

    group.setLayout(grid);
    Button button_1 
= new Button(group, SWT.NONE);
    button_1.setText(
"  增加  ");
    GridData gridData 
= new GridData();
    gridData.grabExcessHorizontalSpace 
= true;
    gridData.horizontalAlignment 
= GridData.CENTER;
    button_1.setLayoutData(gridData);
    
//建立按鈕的事件監聽器
    button_1.addSelectionListener(new Selection(tableViewer, button_1));

    Button button_2 
= new Button(group, SWT.NONE);
    button_2.setText(
"  清空  ");
    gridData 
= new GridData();
    gridData.grabExcessHorizontalSpace 
= true;
    gridData.horizontalAlignment 
= GridData.CENTER;
    button_2.setLayoutData(gridData);
    button_2.addSelectionListener(
new Selection(tableViewer, button_2));
    
// .
    
// .
    
// .
    return pare;

}

private class Selection extends SelectionAdapter {

    
private TableViewer tv;

    
private Object button;

    
public Selection(TableViewer tv, Object button) {

        
this.tv = tv;
        
this.button = button;
    }

    
public void widgetSelected(SelectionEvent e) {

        String str 
= ((Button) e.getSource()).getText();

        
if (str.equals("  增加  ")) {
            Object[][] object 
= new Object[1][4];
            
for (int i = 0, j = index + 1; i < object[0].length; i++)
                object[
0][i] = Integer.toString(j);
            
/* tableViwer的添加行的方法,這個方法可以將數據
             * 添加到表格中,並且不會影響到表格中其他的數據,
             * 而如果使用setInput會把以前在表格中的數據全部替換掉,
             * 當然如果你再使用getInput(),那麼只能獲得以前使用
             * setInput時添加的數據,而後面使用add方法添加的數據
             * 是不會被獲得的。
*/
            tv.add(object);
            index
++;
        }
        
if (str.equals("  清空  ")) {
            
if (tv.getTable().getItemCount() != 0) {

                index 
= tv.getTable().getItemCount();
                
/* removeAll()是Table的方法,將當前表格中
                 * 所有的數據全部清空
*/
                tv.getTable().removeAll();
                ((Button) button).setText(
"  顯示  ");

            }
        }
        
if (str.equals("  顯示  ")) {

            Object[][] object 
= new Object[index][4];
            
for (int i = 0; i < object.length; i++) {
                
for (int j = 0; j < 4; j++) {
                    object[i][j] 
= i + 1;
                }
            }
            tv.setInput(object);
            ((Button) button).setText(
"  清空  ");

        }
    }
}

/****************文件名:JFaceTable.java****************/

public class JFaceTable {

    
/* 用於實現IStructuredContentProvider接口,此接口一般都只
     * 用實現getElements()這個方法,其他的方法爲空就行了
*/
    
class TableViewerContentProvider implements 
                            IStructuredContentProvider{
        
        
/* 這裏的參數就是我們使用setInput()傳進的參數,因爲我使用的是數組
         * 所以接受的參數也是二維數組。
         
*/
        
public Object [] getElements(Object element) {
            
            
//因爲該方法不能返回null,所以要先判斷一下數據的正確性,否則會
            
//報異常。
            if (element instanceof Object [])
            {
                
//首先將此參數轉換成一維數組
                return (Object []) element;
            }
            
else
            {
                
return new Object [0];
            }
        }
        
/* 下面的方法可以設置爲空*/
        
public void dispose() {}

        
public void inputChanged(Viewer arg0, Object arg1, Object arg2) {}
        
    }
    
    
/* 用於實現ITableLabelProvider接口,此接口一般都只
     * 用實現getElements()這個方法,其他的方法爲空就行了
*/
    
class TableViewerLabelProvider implements ITableLabelProvider{
        
/* 這裏的element參數,其實就是我們二維數組中的每一個一維數組,其中保存的是
         * 每一行的所有數據,通過column這個參數依次寫入到表格中的各個字段上。
         * column具體值是多少我們並不知道,因此需要我們來判斷,並根據他裏面的值
         * 來決定我們要將哪個數據返回。同樣,該方法是不能返回NULL的。必須先檢查數
         * 有效性。
*/
        
public String getColumnText(Object element, int column) {

            
if (element instanceof Object [])
            {
                
for (int i = 0; i < ((Object []) element).length; i++)
                {
                    
if (column == i)
                    {
                        
return ((Object []) element)[column].toString();
                    }
                }
            }
            
return "";
        }
        
        
public Image getColumnImage(Object arg0, int arg1) {
            
            
return null;
        }

        
public void addListener(ILabelProviderListener arg0) {}

        
public void dispose() {}

        
public boolean isLabelProperty(Object arg0, String arg1) {

            
return false;
        }

        
public void removeListener(ILabelProviderListener arg0) {}
        
    }
    
/* 下面的方法就是用於創建TableViewer對象的,並返回給主窗口*/
    
public TableViewer creatTableViewer(Composite pare){
        
        
//創建TableViewer對象,這裏有幾個式樣。BORDER:有邊框|MULTI:可以多選
        
//FULL_SELECTION整行選擇。
        TableViewer tableViewer = new TableViewer(pare,SWT.BORDER|SWT.MULTI|SWT.FULL_SELECTION);
        
//獲得TableViewer的table對象,並在後面設置他的表頭是否顯示,
        
//是否具有表格線。
        Table table = tableViewer.getTable();
        table.setHeaderVisible(
true);
        table.setLinesVisible(
true);
        
//設置table的專有表格佈局管理器。
        TableLayout tableLayout = new TableLayout();
        table.setLayout(tableLayout);
        
        
//下面都是設置表頭上的文字和每一列表格佔的比例寬。
        tableLayout.addColumnData(new ColumnWeightData(10));
        
new TableColumn(table,SWT.NONE).setText("序號");
        tableLayout.addColumnData(
new ColumnWeightData(10));
        
new TableColumn(table,SWT.NONE).setText("姓名");
        tableLayout.addColumnData(
new ColumnWeightData(10));
        
new TableColumn(table,SWT.NONE).setText("性別");
        tableLayout.addColumnData(
new ColumnWeightData(10));
        
new TableColumn(table,SWT.NONE).setText("年齡");
        
return tableViewer;
    }
}

 

如果要運行上面的代碼一定要記得設置相應的SWT/JFace的庫文件。設置方法請參看http://blog.csdn.net/jayliu/archive/2005/04/29/367757.aspx

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章