JTable學習筆記
構(gòu)建一個JTable之前,應該設(shè)計好表格的列頭以及行數(shù)據(jù),分別用final數(shù)組保存之:
final String [] names={"First Name","Last Name","Favorite Color",
"Favorite Number","Vegetarian"};
final Object [][] data={
{"Mark","Andrews","Red",new Integer(2),new Boolean(true)},
{"Tom","Chung","Green",new Integer(99),new Boolean(false)}
};
接下來,在創(chuàng)建JTable之前,需要構(gòu)建一個實現(xiàn)了TableModel接口的AbstractTableModel類的實例,TableModel接口規(guī)定了JTable如何訪問表格中數(shù)據(jù)的模型。示例如下:
TableModel dataModel =new AbstractTableModel(){
public int getColumnCount(){return names.length;}//實現(xiàn)這個函數(shù)是必須的,因為抽象類AbstractTableModel中并沒有實現(xiàn)該函數(shù)
public int getRowCount(){return data.length;}//實現(xiàn)這個函數(shù)是必須的,因為抽象類AbstractTableModel中并沒有實現(xiàn)該函數(shù)
public Object getValueAt(int row,int col){return data[row][col];}//實現(xiàn)這個函數(shù)是必須的,因為抽象類AbstractTableModel中并沒有實現(xiàn)該函數(shù)
public String getColumnName(int column){return names[column];}//如果需要自己來命名列名稱,就必須override該方法
@SuppressWarnings("unchecked")
public Class getColumnClass(int col){return getValueAt(0,col).getClass();}//這個方法也因該重寫,因為AbstractTableModel中的實現(xiàn)僅僅是“return Object.class;”,因此我們需要override該方法
public boolean isCellEditable(int row,int col){return true;}//默認均返回false,因此如果希望表格的cell能夠被編輯,就需要override這個函數(shù)
public void setValueAt(Object aValue,int row,int col){//默認情況下,該函數(shù)的函數(shù)體是空的,因此如果希望表格的cell中的值能夠被更改,就必須override該函數(shù)
System.out.println("Setting value to: "+aValue);
data[row][col]=aValue;
}
};
接下來就可以創(chuàng)建JTable了:
JTable tableView=new JTable(dataModel);
至此,表格已經(jīng)創(chuàng)建起來了。如果需要能夠?qū)Ρ砀襁M行更進一步的操作,比如允許用戶編輯表格中各個單元格的內(nèi)容,就需要看看下面的內(nèi)容嘍:
我個人認為編輯表格是以列為單位的,
第一步,需要得到某一列:
TableColumn colorColumn=tableView.getColumn(names[2]);
第二步,需要給該列指定一個實現(xiàn)了TableCellEditor接口的編輯類,DefaultCellEditor類實現(xiàn)了該接口,因此直接構(gòu)建DefaultCellEditor類的一個實例就ok了,需要說明的是,該類的實現(xiàn)方法只有三種,而且分別對應需要JCheckBox、JComboBox、JTextField三種類的實例:
colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
第三步,給該列指定一個實現(xiàn)了TableCellRenderer接口的的渲染類(或稱作呈現(xiàn)/表現(xiàn)類),DefaultTableCellRenderer類實現(xiàn)了該接口,因此直接構(gòu)建DefaultTableCellRenderer的一個實例就ok了:
DefaultTableCellRenderer colorColumnRenderer=new DefaultTableCellRenderer();
colorColumnRenderer.setBackground(Color.pink);
colorColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
colorColumnRenderer.setToolTipText("Click for combo box");
colorColumn.setCellRenderer(colorColumnRenderer);
需要說明的是,DefaultTableCellRenderer能夠設(shè)置的內(nèi)容當然不局限于上述列出的這三個,還有很多,但是有一點很重要,就是如果你希望單元格的內(nèi)容能夠按照某種方式來改變,比如用戶自己編輯了單元格內(nèi)容后,我們?nèi)绻M麊卧癯尸F(xiàn)的內(nèi)容能夠根據(jù)用戶的輸入做更多的變化(而不僅僅是簡單的字符串替換,如果僅僅是字符串替換的話,那就不必廢這么多事了,DefaultTableCellRenderer類自帶的setValue實現(xiàn)方法就能夠完成任務(wù)了),而不在希望單元格的內(nèi)容一成不變了,此時就不能簡單的創(chuàng)建一個DefaultTableCellRenderer類的實例了,而是需要創(chuàng)建一個DefaultTableCellRenderer類的派生類,而且需要override里面的setValue方法,通常我們都這樣做:
DefaultTableCellRenderer numberColumnRenderer=new DefaultTableCellRenderer(){
public void setValue(Object value){
int cellValue=(value instanceof Number) ? ((Number)value).intValue() : 0;
this.setForeground((cellValue > 30) ? Color.black : Color.red);
super.setValue(value);
}
};
在DefaultTableCellRenderer類中setValue方法的修飾符為protected,因此我們不能直接用DefaultTableCellRenderer的實例來使用該方法,而只能通過繼承DefaultTableCellRenderer類,然后在類的內(nèi)部override該方法來實現(xiàn)定制特定的功能,從這里我們也能夠更深刻的理解為什么有些方法要定義成protected了,目的就是為了對外不可見,但是又能夠通過繼承的手段來實現(xiàn)用戶自己的定制,而且有些情況這是很必須的,比如在該處,我們可以試想一下,如果用public來修飾,則用戶可以直接通過產(chǎn)生實例來引用該方法,那么由于該類是作用于整個列的,而不僅僅是一個單元格,那么當你設(shè)定了setValue后,到底是該對列中所有的單元格都有效呢,還是該只對某一個單元格有效呢,這就很難說了。
posted on 2007-12-20 23:20 so true 閱讀(1050) 評論(0) 編輯 收藏 所屬分類: Java