列表在任何一門開發語言中都占有非常重要的地位,在.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 [email protected] 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);
嗯,沒錯,這樣就可以新增一行了,當然,在表格中新增一行遠不止上面示例代碼這麼簡單的,起碼,大部分情況下是需要對行標識進行比對,看是否存在關鍵字相同的一行再作處理,像我所做的商品添加操作,如果請求新添加的商品項已經存在於表格中,那麼事實上只需要將表格中相應商品行的數量加一就可以了,如果之前並沒存在該商品項的情況下,再進行新增一行的操作。