1. 程式人生 > >【JAVA】JTable學習之使用AbstractTableModel (一)

【JAVA】JTable學習之使用AbstractTableModel (一)

Note : 本例項中涉及到了Java中的Vector的使用,建議先了解Vector的使用方法, [不想看我白話的話,就直接跳到後面看程式碼與貼圖,程式碼註釋很詳細]

 

我表示寫這篇文章很糾結、、因為我是比較熱衷於C++的,在Java方面的理解還不是那麼的深刻,萬一理解片面了,誤人子弟了可不是一件好事、、、但是反正不管怎樣,想想還是寫了吧,給大家分享一下我的一些使用方法,一起共同進步才好嘛。


    如果你問我Java中的JTable能幹什麼?那我就能告訴你 JTable絕對不僅僅只是用來存放文字資料的控制元件,在JTable表格控制元件中,資料 與 表格 是分開的,這個分開的意思就是:表格內的資料是單獨存放的 與 JTable本身木有半毛錢關係,你之所以可以在表格內看到資料是因為 JTable 與資料之間存在的 一一對映的資料對映關係,就好比 房子 與人的關係一樣,房子與人是相互獨立的,但是有了房產證的關聯於是乎房子就與人形成對映關係了。

    在Java中 JTable的資料是以TableModel表模式的方式存放的,這個TableModel就是用來存放資料的,當Table初始化的時候通過TableModel獲取表格的 行數、列數、列標題、以及每個單元格存放的資料(至於他們之間是怎樣關聯起來的這裡我們不做討論),於是當表格現實的時候就可以顯示出對應的資料了。

首先,我們先來看一下 JTable的構造方法:

 

構造方法摘要    

JTable() 
構造一個預設的 JTable,使用預設的資料模型、

預設的列模型和預設的選擇模型對其進行初始化。

JTable(int numRows, int numColumns) 
使用 DefaultTableModel 構造具有 numRows 行

和 numColumns 列個空單元格的 JTable。

JTable(Object[][] rowData, Object[] columnNames) 

構造一個 JTable 來顯示二維陣列 rowData 中的值,

其列名稱為 columnNames。

JTable(TableModel dm) 
構造一個 JTable,使用資料模型 dm、預設的列模型

和預設的選擇模型對其進行初始化。

JTable(TableModel dm, TableColumnModel cm)

 
構造一個 JTable,使用資料模型 dm、列模型 cm 

和預設的選擇模型對其進行初始化。

JTable(TableModel dm, TableColumnModel cm,

 ListSelectionModel sm) 
構造一個 JTable,使用資料模型 dm、列模型 cm 

和選擇模型 sm 對其進行初始化。

JTable(Vector rowData, Vector columnNames) 
構造一個 JTable 來顯示 Vector 所組成的 Vector 

rowData 中的值,其列名稱為 columnNames。

 

   從建構函式中我們可以看到 JTable 要麼使用了預設的資料模型,要麼是構造引數中傳遞了資料


這裡我們著重看建構函式
JTable(TableModel dm) 
構造一個 JTable,使用資料模型 dm、預設的列模型和預設的選擇模型對其進行初始化。


    在這個建構函式中,需要傳遞一個數據模TableModel 用來存放資料,當表格現顯示的時候就直接通過這個TableModel來獲取表格的資訊以及資料,我們檢視API可以知道 TableMode是一個介面,需要實現AbstractTableModel的方法,而AbstractTableModel又是一個抽象的類,也就是說 在使用自己的TableModel的時候要重寫一個自己的TableMode類,通過這個Model來控制自己表格的資料,檢視API可以知道 AbstractTableModel中有些方法是已經實現的了,所以我們只需要對自己需要的方法進行重寫:


先看一下 AbstractTableModel的基本方法

int

getColumnCount() 返回該模型中的列數。

String

getColumnName(int columnIndex) 

返回 columnIndex 位置的列的名稱。

int

getRowCount() 返回該模型中的行數。

Object

getValueAt(int rowIndex,int columnIndex) 返回 columnIndex 和 rowIndex 位置的單元格值。

boolean

isCellEditable(int rowIndex,int columnIndex) 

如果 rowIndex 和 columnIndex 位置的單元格是可編輯的,則返回   true。就是設定當前位置的單元格的資料是否可以被編輯 

   

void

setValueAt(Object aValue, int rowIndex, int columnIndex) 

將 columnIndex 和 rowIndex 位置的單元格中的值設定為 aValue。


   看了API的一些基本的方法,這裡我們就通過這些基本的 方法來寫一個基本的TableModel
PS :
  表格既然是一個二維的,那麼表格的資料存放如果也是二維的,那麼資料的一一對映就很容易實現了
  我們知道Vector是一個 一維線性表,存放的資料型別是Object(Java所有類的'爹'),那麼如果我們在 一維的線性表中的每個位置都放一個一維的線性表,那麼 就像把很多條直線 並排放一樣 就變成了一個二維的空間了


下面是一個Model的示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

//

//***************************************************************************

class ModelDemo extends AbstractTableModel

{         /**         *  @author 小悠         */ 

       private Vector TableData;//用來存放表格資料的線性表

       private Vector TableTitle;//表格的 列標題

        

       //注意建構函式是第一個執行的,用於初始化 TableData,TableTitle

       public ModelDemo()

       {

              //先new 一下

              TableData = new Vector();

              TableTitle= new Vector();

               

              //這裡我們假設當前的表格是 3x3的

              //先初始化 列標題,有3列

              TableTitle.add("第一列");

              TableTitle.add("第二列");

              TableTitle.add("第三列");

               

              //初始化3行資料,方便起見直接用String陣列儲存每一行的資料

              //第0行,都顯示錶格的座標

              String []Line1 = {"(0,0)","(0,1)","(0,2)"};

              //第1行

              String []Line2 = {"(1,0)","(1,1)","(1,2)"};

              //第2行

              String []Line3 = {"(2,0)","(2,1)","(2,2)"};

              //將資料掛到線性表形成二維的資料表,形成對映

              TableData.add(Line1);

              TableData.add(Line2);

              TableData.add(Line3);

               

       }

       @Override

       public int getRowCount()

       {

              //這裡是告知表格應該有多少行,我們返回TableData上掛的String陣列個數

              return TableData.size();

       }

  

       @Override

       public int getColumnCount()

       {

              //告知列數,用標題陣列的大小,這樣表格就是TableData.size()行,TableTitle.size()列了

              return TableTitle.size();

       }

  

       @Override

       public Object getValueAt(int rowIndex, int columnIndex)

       {

              //獲取了表格的大小,當然還要獲取資料,根據座標直接返回對應的資料

              //小心 都是從 0開始的,小心下標越界 的問題

              //我們之前是將 String[]掛到了線性表上,所以要先獲取到String[]

              //

              //獲取每一行對應的String[]陣列

              String LineTemp[] = (String[])this.TableData.get(rowIndex);

              //提取出對 應的資料

              return LineTemp[columnIndex];

               

              //如果我們是將 線性表Vector掛到了Vector上要注意每次我們獲取的是 一行線性表

              //例如

              //return ((Vector)TableData.get(rowIndex)).get(columnIndex);

       }

  

       @Override

       public boolean isCellEditable(int rowIndex, int columnIndex)

       {

              //這個函式式設定每個單元格的編輯屬性的

              //這個函式AbstractTableModel已經實現,預設的是 不允許編輯狀態

              //這裡我們設定為允許編輯狀態

              return true;//super.isCellEditable(rowIndex, columnIndex);

       }

       @Override

       public void setValueAt(Object aValue, int rowIndex, int columnIndex)

       {

              //當單元格的資料發生改變的時候掉用該函式重設單元格的資料

              //我們想一下,資料是放在TableData 中的,說白了修改資料就是修改的

              //TableData中的資料,所以我們僅僅在此處將TableData的對應資料修改即可

               

              ((String[])this.TableData.get(rowIndex))[columnIndex]=(String)aValue;

              super.setValueAt(aValue, rowIndex, columnIndex);

              //

              //其實這裡super的方法是呼叫了fireTableCellUpdated()只對應更新了

              //對應單元格的資料

              //fireTableCellUpdated(rowIndex, columnIndex);

       }

}

//建立一個Dialog顯示一下

public class JMain

{

       public static void main(String[] args)

       {               ModelDemo myModel=  new ModelDemo(); 

             JTable table = new JTable(myModel);

             JScrollPane scrollpane = new JScrollPane(table);

             JFrame jf = new JFrame();

             JScrollPane jsp = new JScrollPane(table);

             jf.add(jsp);

             jf.setBounds(00500500);

             jf.setVisible(true);    

       }

}

//*****************************************下面是效果截圖
 

//沒有修改資料的時候

//修改了資料


PS:
    上面說所的都是針對 普通的文字資料,當然JTable不僅僅是用來顯示文字資料的,例如下圖

 

 

本文轉自悠然品鑑 小悠