項目需求:JTable 表格支持按多列排序,首列相同時按次列排序,以此類推,最多支持三列組合排序。點擊表頭切換:升序 → 降序 → 取消排序。支持中文漢字拼音/筆畫排序、數值、日期等多類型比較。

圖示:先按密碼升序,再按用戶名升序,最後按年齡降序的三級排序效果。
┌─────────────────────────────────────────────────────────────┐ │ TableOrder3Table (主控制器) │ ├─────────────────────────────────────────────────────────────┤ │ TableModel (TableOrder3TableMode) ← 數據模型 │ │ TableOrderSorter (Comparator) ← 排序策略入口 │ │ SorterColumnGroupUtil ← 排序列狀態管理(最多3列) │ │ SorterUtil ← 通用比較器實現(反射+Collator)│ │ TableHeaderButton ← 表頭渲染器(顯示排序圖標) │ └─────────────────────────────────────────────────────────────┘
維護三級排序列狀態(列名 + 升降序),邏輯:
public class SorterColumnGroupUtil {
private static String[][] sorterArray = new String[3][2]; // [列名, 升降序]
public static void setColumn(String columnName) {
if (columnName == null) return;
// 邏輯見上述狀態機描述,完整代碼參考源碼
}
// getColumn1/2/3, getColumn1Asc/2Asc/3Asc 獲取器...
}
基於反射獲取對象屬性值,支持多類型、多級、升降序組合比較:
public static int compare(Object o1, Object o2) {
// 1. 反射獲取三級排序屬性值
Object o1Col1 = getFieldByReflect(o1, SorterColumnGroupUtil.getColumn1());
Object o1Col2 = getFieldByReflect(o1, SorterColumnGroupUtil.getColumn2());
Object o1Col3 = getFieldByReflect(o1, SorterColumnGroupUtil.getColumn3());
Object o2Col1 = getFieldByReflect(o2, SorterColumnGroupUtil.getColumn1());
Object o2Col2 = getFieldByReflect(o2, SorterColumnGroupUtil.getColumn2());
Object o2Col3 = getFieldByReflect(o2, SorterColumnGroupUtil.getColumn3());
// 2. 獲取升降序標識
String asc1 = SorterColumnGroupUtil.getColumn1Asc();
String asc2 = SorterColumnGroupUtil.getColumn2Asc();
String asc3 = SorterColumnGroupUtil.getColumn3Asc();
// 3. 3層嵌套 if-else 實現所有組合情況 (2^3 * 排列 = 48種)
// 核心邏輯:比較第1列 → 相等則比較第2列 → 相等則比較第3列
// 每層根據 ASC/DESC 調用 compareAsc/compareDesc
}
// 類型自適應比較:String 使用 Collator(Locale.CHINA) 支持中文排序
// Integer/Long 使用自然排序,null/空值統一處理(升序置後,降序置前)
public static int compareAsc(String s1, String s2) {
if (StringUtils.isBlank(s1)) return 1;
if (StringUtils.isBlank(s2)) return -1;
return Collator.getInstance(Locale.CHINA).compare(s1, s2); // 中文智能排序
}
tableHeader.setDefaultRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JButton btn = new TableHeaderButton();
btn.setText(value.toString());
String sortColumnName = tableModel.getColumnObjectName(column);
// 根據 SorterColumnGroupUtil 狀態設置圖標:arr-up1/2/3.png, arr-down1/2/3.png
if (sortColumnName.equals(getColumn1())) {
btn.setIcon(asc1 ? up1Icon : down1Icon);
} else if (sortColumnName.equals(getColumn2())) { ... }
return btn;
}
});
TableModel 接口,封裝 List<User>getColumnObjectName(int columnIndex) 映射列索引 → 屬性名(如 "userName"),供反射使用getList() 返回可排序的列表引用MouseListener 獲取列索引 → 映射屬性名SorterColumnGroupUtil.setColumn() 更新排序狀態Collections.sort(model.getList(), tableOrderSorter) 執行排序table.updateUI() 刷新視圖 → 表頭渲染器讀取最新狀態顯示圖標Java 默認 String.compareTo() 按 Unicode 編碼排序,中文亂序。解決方案:
Collator chineseCollator = Collator.getInstance(Locale.CHINA); // 或更精確:Collator.getInstance(Locale.SIMPLIFIED_CHINESE) int result = chineseCollator.compare(str1, str2);
collator.setStrength(Collator.TERTIARY) 區分大小寫/聲調com.test.order
├── TableOrder3Test.java # 主入口,啟動 JFrame
├── TableOrder3Table.java # 主控制器,組裝所有組件
├── TableOrder3TableMode.java # TableModel 實現
├── User.java # 實體類,含屬性名常量
├── TableHeaderButton.java # 表頭按鈕渲染器
└── orderutil
├── SorterColumnGroupUtil.java # 排序列狀態管理
├── SorterUtil.java # 核心比較器
└── Constant.java # ASC="1", DESC="-1"
RowSorter (JDK 6+) 替代 Collections.sort,支持視圖層排序不改動模型數據User 替換為泛型 T,配合註解 @Sortable 標記可排序字段這套方案在 JDK 1.6/1.7/1.8 驗證通過,代碼結構清晰、邏輯完整,可直接集成到 Swing 桌面應用中,解決多列排序、中文排序、狀態可視化等實際痛點。