【轉】java JTable排序和過濾


JTable排序

  在Java SE 6中除了java.awt被更新外,javax.swing同時也有了很大的改進。在C/S程序中我們會經常使 用到"表"。如我們可以在查詢數據庫后將查詢結果顯示在表格中。在Java中顯示表格使用的是JTable類。在以前的版本中,JTable只能簡單地顯 示數據,並沒有什么附加的處理功能,而在Java SE 6中的JTable增加了排序和過濾功能。用戶可以單擊列頭進行排序,也可以根據某一列來過濾表 中的數據。

為了使JTable可以對數據進行,必須將RowSorter類和JTable進行關聯。RowSorter是一個抽象類,它負責將JTable中的 數據映射成可排序的數據。在真正使用時,我們將直接使用RowSorter的子類TableRowSorter。下面的代碼顯示了如何將TableRowSorter類和JTable相關聯。

 

[java]  view plain copy
  1. TableModel model = new DefaultTableModel(rows, columns);  
  2. JTable table = new JTable(model);  
  3. RowSorter sorter = new TableRowSorter(model);  
  4. table.setRowSorter(sorter);  

 

上面代碼首先建立一個TableModel,然后將這個TableModel的實例同時傳遞給了JTable和RowSorter。下面是一個使用JTable排序的簡單的例子。

 

[java]  view plain copy
  1. import javax.swing.*;  
  2. import javax.swing.table.*;  
  3. import java.awt.*;  
  4.   
  5. public class TestSortedTable {  
  6.     public static void main(String args[]) {  
  7.         JFrame frame = new JFrame("JTable的排序測試");  
  8.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  9.         // 表格中顯示的數據  
  10.         Object rows[][] = { { "王明""中國"44 }, { "姚明""中國"25 },  
  11.                 { "趙子龍""西蜀"1234 }, { "曹操""北魏"2112 },  
  12.                 { "Bill Gates""美國"45 }, { "Mike""英國"33 } };  
  13.         String columns[] = { "姓名""國籍""年齡" };  
  14.         TableModel model = new DefaultTableModel(rows, columns);  
  15.         JTable table = new JTable(model);  
  16.         RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);  
  17.         table.setRowSorter(sorter);  
  18.         JScrollPane pane = new JScrollPane(table);  
  19.         frame.add(pane, BorderLayout.CENTER);  
  20.         frame.setSize(300150);  
  21.         frame.setVisible(true);  
  22.     }  
  23. }  

 

 

圖3顯示的是按"年齡"進行降序排列。但我們發現一個奇怪的問題,就是"年齡"字段並不是按數值類型進行排序的,而是按字符類型進行排序的。


出現這種情況是因為在默認情況下DefaultTableModal的列是Object類型。而要想使JTable按數值進行排序,必須要覆蓋DefaultTableModal的getColumnClass方法。

 

[java]  view plain copy
  1. TableModel model = new DefaultTableModel(rows, columns) {  
  2.     public Class getColumnClass(int column) {  
  3.         Class returnValue;  
  4.         if ((column >= 0) && (column < getColumnCount())) {  
  5.             returnValue = getValueAt(0, column).getClass();  
  6.         } else {  
  7.             returnValue = Object.class;  
  8.         }  
  9.         return returnValue;  
  10.     }  
  11. };  

 

 

圖4顯示了按"年齡"進行排序的界面,看看,是不是按數值進行排序了。

JTable過濾

在JTable中通過抽象類RowFilter類對行進行過濾。和排序不同,你可以不建立它們的子類,而使用這個抽象類的6個靜態方法。

·andFilter
·dateFilter(RowFilter.ComparisonType type, Date date, int... indices)
·notFilter(RowFilter<M,I> filter)
·numberFilter(RowFilter.ComparisonType type, Number number, int... indices)
·orFilter
·regexFilter(String regex, int... indices)

其中andFilter()、orFilter()以及notFilter()方法的功能是將當前的過濾條件和其它的過濾條件進行組合。如在同時比較日期和數值時需要將日期過濾和數值過濾進行組合。這些組合是非常簡單的。

RowFilter的類型比較允許你進行4種關系的比較,等於、不等於、大於或小於。我們可以通過指定某一列進行過濾,也可以對所有的列進行過濾。這 其中最為有趣的也許是正則表達式過濾(regular expression filter,或簡稱為regex filter)。使用這個過濾器可以對 表中數據進行更高級的過濾。下面是實現一個簡單過濾器的代碼。

 

[java]  view plain copy
  1. import javax.swing.*;  
  2. import javax.swing.table.*;  
  3. import java.awt.*;  
  4. import java.awt.event.*;  
  5.   
  6. public class TestFilter {  
  7.     public static void main(String args[]) {  
  8.         JFrame frame = new JFrame("JTable的過濾測試");  
  9.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  10.         Object rows[][] = { { "王明""中國"44 }, { "姚明""中國"25 },  
  11.                 { "趙子龍""西蜀"1234 }, { "曹操""北魏"2112 },  
  12.                 { "Bill Gates""美國"45 }, { "Mike""英國"33 } };  
  13.         String columns[] = { "姓名""國籍""年齡" };  
  14.         TableModel model = new DefaultTableModel(rows, columns) {  
  15.             public Class getColumnClass(int column) {  
  16.                 Class returnValue;  
  17.                 if ((column >= 0) && (column < getColumnCount())) {  
  18.                     returnValue = getValueAt(0, column).getClass();  
  19.                 } else {  
  20.                     returnValue = Object.class;  
  21.                 }  
  22.                 return returnValue;  
  23.             }  
  24.         };  
  25.         final JTable table = new JTable(model);  
  26.         final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(  
  27.                 model);  
  28.         table.setRowSorter(sorter);  
  29.         JScrollPane pane = new JScrollPane(table);  
  30.         frame.add(pane, BorderLayout.CENTER);  
  31.         JPanel panel = new JPanel(new BorderLayout());  
  32.         JLabel label = new JLabel("過濾");  
  33.         panel.add(label, BorderLayout.WEST);  
  34.         final JTextField filterText = new JTextField("");  
  35.         panel.add(filterText, BorderLayout.CENTER);  
  36.         frame.add(panel, BorderLayout.NORTH);  
  37.         JButton button = new JButton("過濾");  
  38.         button.addActionListener(new ActionListener() {  
  39.             public void actionPerformed(ActionEvent e) {  
  40.                 String text = filterText.getText();  
  41.                 if (text.length() == 0) {  
  42.                     sorter.setRowFilter(null);  
  43.                 } else {  
  44.                     sorter.setRowFilter(RowFilter.regexFilter(text));  
  45.                 }  
  46.             }  
  47.         });  
  48.         frame.add(button, BorderLayout.SOUTH);  
  49.         frame.setSize(300250);  
  50.         frame.setVisible(true);  
  51.     }  
  52. }  

圖5是上面程序的運行界面。

 

以下是銷售系統中表格中實現過濾功能,過濾第5列即銷售列(字段包括“已售”、“預訂"、”未售“),

 

[java]  view plain copy
  1. if(displaySaleStatus==0&&displayBookStatus==0&&displayNotBookStatus==0)  
  2.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("什么都不顯示哦"4));  
  3. if(displaySaleStatus==1&&displayBookStatus==0&&displayNotBookStatus==0)  
  4.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("已售"4));  
  5. else if(displaySaleStatus==0&&displayBookStatus==1&&displayNotBookStatus==0)  
  6.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("預訂"4));  
  7. else if(displaySaleStatus==0&&displayBookStatus==0&&displayNotBookStatus==1)  
  8.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("未訂"4));  
  9. else if(displaySaleStatus==1&&displayBookStatus==1&&displayNotBookStatus==0)  
  10.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("已售|預訂"4));  
  11. else if(displaySaleStatus==0&&displayBookStatus==1&&displayNotBookStatus==1)  
  12.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("預訂|未訂"4));  
  13. else if(displaySaleStatus==1&&displayBookStatus==0&&displayNotBookStatus==1)  
  14.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("已售|未訂"4));  
  15. else if(displaySaleStatus==1&&displayBookStatus==1&&displayNotBookStatus==1)  
  16.     ((TableRowSorter)this.table.getRowSorter()).setRowFilter(RowFilter.regexFilter("已售|預訂|未訂"4));//全部顯示,或setRowFilter(null)  

一下是地震發布系統中過濾第2列即震級列(字段為Float型)

 

[java]  view plain copy
  1. /** 
  2.  * (大、中、小地震)顯示按鈕事件處理過程 
  3.  * */  
  4. @SuppressWarnings("unchecked")  
  5. private void showActionHandle(){  
  6.     boolean showBigEqStatus=showBigEqBut.isSelected();  
  7.     boolean showMiddleEqStatus=showMiddleEqBut.isSelected();  
  8.     boolean showSmallEqStatus=showSmallEqBut.isSelected();  
  9.     if(showBigEqStatus==false&&showMiddleEqStatus==false&&showSmallEqStatus==false)  
  10.         ((TableRowSorter)this.getRowSorter()).setRowFilter(RowFilter.numberFilter(ComparisonType.AFTER, 100,2));  
  11.     if(showBigEqStatus==true&&showMiddleEqStatus==false&&showSmallEqStatus==false){  
  12.         ((TableRowSorter)this.getRowSorter()).setRowFilter(RowFilter.numberFilter(ComparisonType.AFTER,TableAttribute.BIG_EARTHQUAKE_THRESHOLD,2));  
  13.     }  
  14.     else if(showBigEqStatus==false&&showMiddleEqStatus==true&&showSmallEqStatus==false){  
  15.         List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);  
  16.         filters.add(RowFilter.numberFilter(ComparisonType.AFTER,TableAttribute.MIDDLE_EARTHQUAKE_THRESHOLD,2));  
  17.         filters.add(RowFilter.numberFilter(ComparisonType.BEFORE,TableAttribute.BIG_EARTHQUAKE_THRESHOLD,2));  
  18.         RowFilter<Object,Object> fooBarFilter = RowFilter.andFilter(filters);  
  19.         ((TableRowSorter)this.getRowSorter()).setRowFilter(fooBarFilter);  
  20.     }  
  21.     else if(showBigEqStatus==false&&showMiddleEqStatus==false&&showSmallEqStatus==true){  
  22.         ((TableRowSorter)this.getRowSorter()).setRowFilter(RowFilter.numberFilter(ComparisonType.BEFORE,TableAttribute.MIDDLE_EARTHQUAKE_THRESHOLD,2));  
  23.     }  
  24.     else if(showBigEqStatus==true&&showMiddleEqStatus==true&&showSmallEqStatus==false){  
  25.         ((TableRowSorter)this.getRowSorter()).setRowFilter(RowFilter.numberFilter(ComparisonType.AFTER,TableAttribute.MIDDLE_EARTHQUAKE_THRESHOLD,2));  
  26.     }  
  27.     else if(showBigEqStatus==false&&showMiddleEqStatus==true&&showSmallEqStatus==true){  
  28.         ((TableRowSorter)this.getRowSorter()).setRowFilter(RowFilter.numberFilter(ComparisonType.BEFORE,TableAttribute.BIG_EARTHQUAKE_THRESHOLD,2));  
  29.     }  
  30.     else if(showBigEqStatus==true&&showMiddleEqStatus==false&&showSmallEqStatus==true){  
  31.         List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);  
  32.         filters.add(RowFilter.numberFilter(ComparisonType.AFTER,TableAttribute.BIG_EARTHQUAKE_THRESHOLD,2));  
  33.         filters.add(RowFilter.numberFilter(ComparisonType.BEFORE,TableAttribute.MIDDLE_EARTHQUAKE_THRESHOLD,2));  
  34.         RowFilter<Object,Object> fooBarFilter = RowFilter.orFilter(filters);  
  35.         ((TableRowSorter)this.getRowSorter()).setRowFilter(fooBarFilter);  
  36.     }  
  37.     else if(showBigEqStatus==true&&showMiddleEqStatus==true&&showSmallEqStatus==true){  
  38.         ((TableRowSorter)this.getRowSorter()).setRowFilter(RowFilter.numberFilter(ComparisonType.AFTER, 0,2));  
  39.     }  
  40. }  




 

補充:將表格視圖中的行號映射到模型中對應的行號,才能正確地得到行的內容,尤其是自動排序后,視圖中的行號與表格模型中的行號不一致,TableModel中的方法getValueAt(row,column)中的row指模型中的row,而通過table.getSelectedRow()或者事件處理中通過table.rowAtPoint(e.getPoint())得到row指視圖中的row,因此必須將視圖中的row轉化為model中的row:

int  view_row    = table.rowAtPoint(e.getPoint()); //獲得視圖中的行索引
 int  view_col     = table.columnAtPoint(e.getPoint()); //獲得視圖中的列索引
 int  model_row= table.convertRowIndexToModel(row);//將視圖中的行索引轉化為數據模型中的行索引
 int  model_col = table.convertColumnIndexToModel(col);//將視圖中的列索引轉化為數據模型中的列索引

本文轉自:http://blog.csdn.net/b_h_l/article/details/7771944


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM