列表在任何一門開發語言中都占有非常重要的地位,在.Net中有GridView,在extjs中有GridPanel。。。,而在java Swing中,它的名字叫JTable。這兩天在研究JTable的使用,也有一些收獲,所以在這裡跟大家分享交流一下,下面的內容將包括:1)JTable的基本用法;2)怎樣為JTable添加行點擊響應事件,雙擊後打開窗口;3)怎樣為JTable的行添加標識,如行id等;4)怎樣在JTable中動態添加新行;
1)JTable的基本用法:
我用的IDE是NetBeans,由於也是簡單做幾個頁面的客戶端,主要還是Web開發的,所以暫時不打算深究java winform開發,所以界面怎麼快就怎麼做了,我直接在窗體的“設計”模式下直接拖“表格”出來就了事,在默認的情況下,這個表格還會有幾行幾列的填充內容的,如果需要編輯,可以先點擊表格進入它的編輯狀態,然後右擊,選擇“表內容”就可以進行表格的行和列的編輯了,不過通常情況下,表格的內容都是動態生成的,所以在控件上直接編輯它的內容的意義是不大的,當然,做DEMO時比較有用。
怎樣為JTable初始化內容呢?我的習慣是在frame的構造方法來完成,其實通過查API可以得知,JTable支持多種構造方法,而我認為動態生成數據來說,用Vector對象的形式來生成列頭配置及數據配置是比較簡單直觀的方法,下面來看個例子:
String[] columnModel = {"時間","編號","金額","操作員"};
Vector cmVector = new Vector();
for(int i = 0,cmCount = columnModel.length;i < cmCount;i++){
cmVector.addElement(columnModel[i]);
}
//繪制數據模型
Vector dataVector = new Vector();
TempOrdersList tempOrderList = TempOrdersManager.getInstance().getList();
int billCount = tempOrderList.size();
if(billCount > 0){
for(int j = 0;j < billCount;j++){
TempOrders orderItem = (TempOrders)tempOrderList.get(j);
String id = orderItem.getId();
String time = orderItem.getTime();
String no = orderItem.getNo();
float total = orderItem.getTotal();
String user = orderItem.getUser();
CustomTableCell idCell = new CustomTableCell(id,no,orderItem);
Vector rowVector = new Vector();
rowVector.addElement(time);
rowVector.addElement(idCell);
rowVector.addElement(total);
rowVector.addElement(user);
dataVector.addElement(rowVector);
rowVector = null;
idCell = null;
orderItem = null;
}
}
DefaultTableModel tableModel = new DefaultTableModel(dataVector,cmVector){
@Override
public boolean isCellEditable(int row,int column){
//只允許用戶對第四列的數據進行編輯(第四列是數量)
if(column == 4){
return true;
}else{
return false;
}
}
};
BillTable.setModel(tableModel);
cmVector = null;
dataVector = null;
使用Vector對象作為構造方法的對象時,要傳入兩個Vector的實例,第一個是保存數據的Vector,第二個參數是保存列頭信息的Vector,在
示例中的dataVector是通過遍歷一個list對象而動態填充內容的,在實例化並初始化好Vector後,只要調用JTable的setModel方法,就可以將列頭及數據的信息顯示在表格中啦。
2)怎樣添加行點擊事件
首先,在JTable的設計視圖中先選中JTable,然後右擊,在事件的彈出菜單中依次選中"mouse-click”就可以捕捉表格的點擊事件了,在這個事件監聽方法中,會傳入一個java.awt.event.MouseEvent類的實例evt,用evt.getClickCount(),就可以知道觸發該事件時用戶的點擊次數,只要這個方法返回的值大於等於2,就說明用戶雙擊了,下面的示例代碼,供大家參考:
if(evt.getClickCount() >= 2){
int rowIndex = productTable.rowAtPoint(evt.getPoint());
int columnIndex = Common.getIndetityColumn(productTable);
//如果沒有找到帶有標記的列,就不向下執行了
if(columnIndex == -1){
return;
}
CustomTableCell identifyCell = (CustomTableCell)productTable.getValueAt(rowIndex, columnIndex);
String productId = identifyCell.getId();
ProductDetail productDetail = new ProductDetail(productId);
Common.centerWindow(productDetail);
//productDetail.setVisible(true);
}
3)怎樣為JTable添加行標識
我們知道,JTable的每一個單元格,要求的值類型是一個Object的實例,也就是說,只要是一個對象就可以了,這個機制,給了我們非常大的發揮空間,我們可以在一個單元格中存放任意類型的對象,只要在這個對象中重寫一下toString()方法,將我們希望在單元格中顯示的內容return出來就可以了,只JTable本身,並沒有提供設置行id等識別表格行對象的方法,所以我想到了自己定義一個單元格對象,每一行中至少有一個單元格是我所定義這個對象的實例,這樣,在捕捉事件的時候,只要我從觸發事件的行中提取到這個單元格對象出來,就解決了行標記的問題了。我定義的自定義單元格對象是這樣的,有三個屬性,一個是id,一個是text,還有一個是自定義對象項,id當然是這個行的唯一標識啦,text是單元格中要顯示的內容,而自定義對象項,則是為了方便在這個單元格對象中附加一個對象,方便以後調用的,好了,看看我寫的代碼:
查看本欄目
/**
* 自定義的表格單元格對象
* @author waitatlee@163.com 2011-6-17
*/
public class CustomTableCell {
private String cellText = "";
private String cellId = "";
private Object customObj = null;
/**
* 循例都要有空構造方法的啦
*/
public CustomTableCell(){
}
/**
* 只需初始化單元格顯示內容
* @param _cellText
*/
public CustomTableCell(String _cellText){
this.setText(_cellText);
}
/**
* 同時初始化單元格的id和顯示文本
* @param _cellId
* @param _cellText
*/
public CustomTableCell(String _cellId,String _cellText){
this.setText(_cellText);
this.setId(_cellId);
}
/**
* 完整參數的構造方法
* @param _cellId
* @param _cellText
* @param _customObj
*/
public CustomTableCell(String _cellId,String _cellText,Object _customObj){
this.setId(_cellId);
this.setText(_cellText);
this.setCustomObj(_customObj);
}
/**
* 設置單元格顯示的文本
* @param _cellText
*/
public void setText(String _cellText){
this.cellText = _cellText;
}
/**
* 獲取單元格顯示的文本(默認為"")
* @return
*/
public String getText(){
return this.cellText;
}
/**
* 設置與單元格綁定的id值
* @param _cellId
*/
public void setId(String _cellId){
this.cellId = _cellId;
}
/**
* 獲取與單元格綁定的id值(默認為"")
* @return
*/
public String getId(){
return this.cellId;
}
/**
* 設置單元格附加的自定義對象(按需調用)
* @param _obj
*/
public void setCustomObj(Object _obj){
this.customObj = _obj;
}
/**
* 獲取單元格附加的自定義對象(默認為null)
* @return
*/
public Object getCustomObj(){
return this.customObj;
}
@Override
/**
* 重寫的方法,jtable將根據這個方法的返回值來決定單元格顯示的內容
*/
public String toString(){
return this.getText();
}
}
事實證明,這個類非常好用,特別是它的customObj方法,能將一個對象保存在行內的單元格中,在進行行點擊響應的時候,再提取了出來,非常強大,示例:
CustomTableCell idCell = (CustomTableCell)table.getValueAt(i, idColumnIndex);
float quantity = Float.parseFloat(String.valueOf(table.getValueAt(i, quantityColumnIndex)));
Product product = (Product)idCell.getCustomObj();
這樣,通過自定義的的單元格對象,能將整個對象獲取出來,再作任何復雜的處理,都不怕啦,因為,你已經擁有所需要的一切了。
4)怎樣在JTable中動態添加新行
其實這個問題非常簡單,只要根據列模型生成相應的行對象,然後通過調用JTable的model對象的addRow方法就ok了,由於過於簡單,所以直接貼代碼來說明問題:
DefaultTableModel selectionTM = (DefaultTableModel)selectionTable.getModel();
Object[] tempRow = {code,idCell,spec,price,quantity,subTotal};
selectionTM.addRow(tempRow);
嗯,沒錯,這樣就可以新增一行了,當然,在表格中新增一行遠不止上面示例代碼這麼簡單的,起碼,大部分情況下是需要對行標識進行比對,看是否存在關鍵字相同的一行再作處理,像我所做的商品添加操作,如果請求新添加的商品項已經存在於表格中,那麼事實上只需要將表格中相應商品行的數量加一就可以了,如果之前並沒存在該商品項的情況下,再進行新增一行的操作。