JTable Keep Group of Rows always first when sorting ASC or DESC

76 Views Asked by At

I Have a JTable I am using to show some data, the data consists basically of (Key,Value) pairs.

I enable sorting of the Table by the Key Column.

But I need a group of keys to always be at the top no matter if it is sorted ascending or descending.

Exameple :

Unsorted

Key Value
Key A Value A
Key C Value C
Key B Value B
Key 1 Value 1
Key 3 Value 3
Key 2 Value 2
Key 4 Value 4

Sorted ASC

Key Value
Key A Value A
Key B Value B
Key C Value C
Key 1 Value 1
Key 2 Value 2
Key 3 Value 3
Key 4 Value 4

Sorted DESC

Key Value
Key C Value C
Key B Value B
Key A Value A
Key 4 Value 4
Key 3 Value 3
Key 2 Value 2
Key 1 Value 1

I created a rowsorter with a comparator and was able to get the Sorted ASC,

final TableRowSorter<CTableModel> sorter = new TableRowSorter<CTableModel>((CTableModel) this.getModel());
sorter.setComparator(0, new CJTableComparator());
sorter.setSortable(1, false);

but the defaultrowsorter orders the desc by multiplying the row numbers by -1.

private int compare(int model1, int model2) {
...    
    if (sortOrder == SortOrder.DESCENDING) {
        result *= -1;
    }

and seeing how the method is private I cannot override it.

Does anyone have any ideas on how I could handle this?

class CJTableComparator implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {

        CTableModel model = ((CTableModel)CJTable.this.getModel());

        String so1 = o1.toString();
        String so2 = o2.toString();

        boolean isHeader1 = model.isHeader(so1);
        boolean isHeader2 = model.isHeader(so2);


        if(isHeader1 == isHeader2){

        }else if(isHeader1){
            so1 = "0"+so1;
            so2 = "9"+so2;
        }else if(isHeader2){
            so1 = "9"+so1;
            so2 = "0"+so2;
        }

        return so1.toString().compareToIgnoreCase(so2.toString());
    }
}

Table Model

public class CTableModel extends DefaultTableModel {

    private final HashMap<String, CTableModelRow> rowsbyId = new HashMap<String, CTableModelRow>();

    private final HashMap<String, CTableModelRow> rowsHeaders = new HashMap<String, CTableModelRow>();

    static Object[][] empty = {{}};

    private static final String[] DEFALT_COLUMNS = {"TAG", "VALUE", "PREV"};

    public CTableModel (){
        super(empty,DEFALT_COLUMNS);
        this.setRowCount(0);
    }

    public CTableModelRow getRowByNumber(int number){
        return rowsbyNumber.get(number);
    }

    public boolean isHeader(String key){
        return rowsHeaders.containsKey(key);
    }
}

END.

0

There are 0 best solutions below