這個問題糾結了很久很久,目前網上好像還沒有人遇到過像我這樣比較繁雜的問題,今天終於搞定了,分享給大家看一看
情況是這樣的,我做一個關於SWING的工程,當然會用到大量的表格最早清空表格是這樣寫的
// DefaultTableModel model = (DefaultTableModel) table.getModel();
// for (int i = model.getRowCount() - 1; i >= 0; i--) {
// model.removeRow(i);
// }
用這個方法是有問題的,因爲是JTable >> TableModel >> TableData(Vector或String[])這樣的映射關係,如果用上面的方法,如果數據增加或減少都不會通知TableModel ,就導致每次清數據就報數據越界異常ArrayIndexOutOfBoundsException。
如果直接清理數據是會通知上層的監聽,改變模型
((DefaultTableModel) table.getModel()).getDataVector().clear(); //清除表格數據
((DefaultTableModel) table.getModel()).fireTableDataChanged();//通知模型更新
table.updateUI();//刷新表格
這樣做了,程序好像是不出問題了,但是如果對錶格做了排序操作,再看看,程序是不出錯了,但是每加載一行,就看到表格會做一次排序,這個過程的開銷很大,如果數據量大的話,甚至導致內存溢出。經過一天半的研究,跟蹤,終於找到了問題所在,創建表的時候,引用了排序器,排序器的監聽是一個獨立於JTable >> TableModel >> TableData之外,又在後臺影響着這三者之間的關係的一個人,在程序調試時,很難找到他在那裏影響的,最終在JDK API裏發現了一點端倪
javax.swing
類 RowSorter<M>
java.lang.Object javax.swing.RowSorter<M>
- 類型參數:
M
- 底層模型的類型
setSortKeys
public abstract void setSortKeys(List<? extends RowSorter.SortKey> keys)
- 設置當前排序鍵。
-
- 參數:
keys
- 新的SortKeys
;null
是指定一個空列表的簡寫,表示視圖應該是未排序的。
toggleSortOrder
public abstract void toggleSortOrder(int column)
- 顛倒指定列的排序順序。調用此方法時,由子類提供具體行爲。通常,如果指定列已經是主要排序列,則此方法將升序變爲降序(或將降序變爲升序);否則,使指定列成爲主要排序列,並使用升序排序順序。如果指定列不可排序,則此方法沒有任何效果。
如果此方法導致更改排序順序和排序操作,則它將發送適當的
RowSorterListener
通知。 -
- 參數:
column
- 要切換排序順序的列,就底層模型而言- 拋出:
IndexOutOfBoundsException
- 如果列超出底層模型的範圍
上面這兩個方法很像,但又有區別,我先用toggleSortOrder(int column) 這個column必須有一個有效的列號,就是說,不能用-1,這個方法是不能取消對錶的排序選中的。那麼另一個方法setSortKeys(List<? extendsRowSorter.SortKey>
keys),這個就比較難了,我也不知道應該傳什麼參數,再看參數說明:null
是指定一個空列表的簡寫,表示視圖應該是未排序的。“應該”兩字說的實在是詭異,我就把它當成死馬醫,看看到底行不行,嘿嘿,通過方法:rowSort.setSortKeys(null);把表格還原到不排序的狀態,就達到我想要的結果了,大功終於告成!
下面是方法實現的具體代碼,請大家欣賞
1. Jtable 排序
簡單的排序,按字符串的ASCII碼排序
table.setAutoCreateRowSorter(true);
2,Jtable 自定義排序
/**
*定義按數字排序算法
* @author black
* @since 2011-10-20
*/
public class OrderNumberComparator implements Comparator{
public int compare(Object o1, Object o2) {
int i = (Integer) o1 - (Integer) o2;
return i;
}
}
定義表的時候,選擇按自定義算法排序的字段,如果不設置,默認按字符串的ASCII碼排序
JTable dataGrid=new JTable ();
DefaultTableModel model = (DefaultTableModel) this.dataGrid.getModel();
TableRowSorter<TableModel> sorter=new TableRowSorter<TableModel>(model);
//sorter.setSortable(0, false);
sorter.setComparator(0, new cimframe.util.OrderNumberComparator());
sorter.setComparator(3, new cimframe.util.OrderNumberComparator());
sorter.setComparator(4, new cimframe.util.OrderNumberComparator());
sorter.setComparator(5, new cimframe.util.OrderNumberComparator());
dataGrid.setRowSorter(sorter);
3,Jtable 清空
/***
* 清除JTable數據
*****/
public static synchronized void clearTable(JTable table) {
try {
RowSorter rowSort = table.getRowSorter();
if (rowSort != null) {
rowSort.setSortKeys(null);// 如果使用了排序器,先清除對錶的排序
}
((DefaultTableModel) table.getModel()).getDataVector().clear();
((DefaultTableModel) table.getModel()).fireTableDataChanged();
table.updateUI();
} catch (Exception ex) {
log.error(ex);
}
}