首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JTable 多列排序完整實現:支持中文漢字、三級排序、自定義比較器與圖標反饋

     編輯:Java 綜合教學

需求背景與效果預覽

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

多列排序效果圖

圖示:先按密碼升序,再按用戶名升序,最後按年齡降序的三級排序效果。

核心架構設計

┌─────────────────────────────────────────────────────────────┐
│                    TableOrder3Table (主控制器)                │
├─────────────────────────────────────────────────────────────┤
│  TableModel (TableOrder3TableMode)  ← 數據模型                │
│  TableOrderSorter (Comparator)    ← 排序策略入口              │
│  SorterColumnGroupUtil            ← 排序列狀態管理(最多3列)   │
│  SorterUtil                       ← 通用比較器實現(反射+Collator)│
│  TableHeaderButton                ← 表頭渲染器(顯示排序圖標)   │
└─────────────────────────────────────────────────────────────┘

關鍵組件實現詳解

1. 排序列狀態管理器:SorterColumnGroupUtil

維護三級排序列狀態(列名 + 升降序),邏輯:

  • 新列點擊:依次填入第 1/2/3 主排序列,默認升序
  • 已有列再次點擊:升序 ↔ 降序 切換;降序時移除該列,後續列前移
  • 三列已滿點擊新列:忽略(或可按業務選擇替換策略)
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 獲取器...
}

2. 通用比較器核心:SorterUtil

基於反射獲取對象屬性值,支持多類型、多級、升降序組合比較:

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); // 中文智能排序
}

3. 表頭渲染器:動態顯示排序圖標

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;
    }
});

4. TableModel 實現:TableOrder3TableMode

  • 實現 TableModel 接口,封裝 List<User>
  • getColumnObjectName(int columnIndex) 映射列索引 → 屬性名(如 "userName"),供反射使用
  • 提供 getList() 返回可排序的列表引用

完整交互流程

  1. 用戶點擊表頭 → MouseListener 獲取列索引 → 映射屬性名
  2. 調用 SorterColumnGroupUtil.setColumn() 更新排序狀態
  3. 調用 Collections.sort(model.getList(), tableOrderSorter) 執行排序
  4. 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) 區分大小寫/聲調
  • 性能優於自定義拼音映射表,JDK 原生實現

項目結構與運行

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"

源碼獲取與聯繫

擴展建議

  1. 性能優化:大數據量時使用 RowSorter (JDK 6+) 替代 Collections.sort,支持視圖層排序不改動模型數據
  2. 泛型化:將 User 替換為泛型 T,配合註解 @Sortable 標記可排序字段
  3. 持久化排序狀態:用戶偏好保存至配置文件/數據庫,下次打開恢復
  4. 表頭右鍵菜單:清除排序、鎖定列、隱藏列等高級交互

這套方案在 JDK 1.6/1.7/1.8 驗證通過,代碼結構清晰、邏輯完整,可直接集成到 Swing 桌面應用中,解決多列排序、中文排序、狀態可視化等實際痛點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved