2017-11-16 1 views
0

ich eine JTable, wo mehrere Spalten enthalten eine Zahl aus einer Aufzählungen wie folgt aus:Java: Um eine JTable nach Spalten von Enum

public static enum IMPORT_CONF_OPERATION_RESULT { 
    OK(0, "OK"), 
    ERROR(1, "ERROR"), 
    WAITING(2, "WAITING"); 
    /* ... */ 
} 

So brauchte ich Methode Looping getValueAt() von Tabellenmodell außer Kraft zu setzen durch Aufzählungswerte, um den entsprechenden String für jede Zeile zu dekodieren und zurückzugeben, da in der Datenbank, aus der die Daten stammen, die numerischen Werte gespeichert werden. Nun, wenn der Benutzer auf die entsprechende Header-Spalte klickt, werden die Zeilen nach numerischen Werten sortiert, aber ich möchte sie in alphabetischer Reihenfolge sortieren. Soll ich sort() Methode des Tabellenmodells überschreiben? Schleifen Sie nicht so oft durch Enum-Werte, um die Beschreibung ineffizient zu machen? Würde es das Rendern von Tabellen verlangsamen?

UPDATE

Dies könnte eine Lösung sein, folgende zu dem, was STaefi vorgeschlagen, innerhalb DefaultTableModelField meine erweitert:

@Override 
public void sort(int col, boolean ascendest) { 
    ColumnProperties columnProperties = this.mapColumn.get(col); 
    if (COLUMN_NAME_ENTITY.equals(columnProperties.getInfo()) || 
     COLUMN_OPERATION_TYPE.equals(columnProperties.getInfo()) || 
     COLUMN_OPERATION_RESULT.equals(columnProperties.getInfo()) || 
     COLUMN_ELABORATION_TYPE.equals(columnProperties.getInfo()) || 
     COLUMN_EVENT_STATE.equals(columnProperties.getInfo())) { 
     Collections.sort((List<TableImportConfEvent>)this.value, new EnumColumnSorter(ascendest, columnProperties.getInfo())); 
     this.fireTableDataChanged(); 
    } 
    else { 
     super.sort(col, ascendest); 
    } 
} 

private class EnumColumnSorter implements Comparator<TableImportConfEvent> { 

    private int ascending; 
    private String columnName; 
    public EnumColumnSorter(boolean ascendest, String columnName) { 
     this.ascending = ascendest ? 1 : -1; 
     this.columnName = columnName; 
    } 
    @Override 
    public int compare(TableImportConfEvent o1, TableImportConfEvent o2) { 
     String decodedString1 = ""; 
     String decodedString2 = ""; 
     if (COLUMN_NAME_ENTITY.equals(this.columnName)) { 
      decodedString1 = getEntityName(o1.getEntityType()); 
      decodedString2 = getEntityName(o2.getEntityType()); 
     } 
     else if (COLUMN_OPERATION_TYPE.equals(this.columnName)) { 
      decodedString1 = getOperationName(o1.getOperationType()); 
      decodedString2 = getOperationName(o2.getOperationType()); 
     } 
     else if (COLUMN_OPERATION_RESULT.equals(this.columnName)) { 
      decodedString1 = getResultName(o1.getOperationResult()); 
      decodedString2 = getResultName(o2.getOperationResult()); 
     } 
     else if (COLUMN_ELABORATION_TYPE.equals(this.columnName)) { 
      decodedString1 = getResultName(o1.getOperationResult()); 
      decodedString2 = getResultName(o2.getOperationResult()); 
     } 
     else if (COLUMN_EVENT_STATE.equals(this.columnName)) { 
      decodedString1 = getStateName(o1.getEventState()); 
      decodedString2 = getStateName(o2.getEventState()); 
     } 
     return (decodedString1.compareTo(decodedString2)) * this.ascending; 
    } 
} 

Antwort

1

für jede Zeile Schleifen über den ENUM-Werte zu vermeiden, die Sie erstellen möchten, können a static final HashMap<Integer,IMPORT_CONF_OPERATION_RESULT>, um die Zuordnung der Werte zu den entsprechenden Labels zu speichern und sie in einem statischen Block innerhalb Ihrer Enumeration zu initialisieren. Dann können Sie einen public static String getLabelByValue(int value) Cache verwenden und O(n) vermeiden, um das Etikett jedes Mal nachzuschlagen.

Zum Steuern der Sortierreihenfolgen und Sortieraktionen möchten Sie vielleicht nach TableRowSorter gehen, aber wenn Sie die getValueAt für Ihr Modell überschrieben haben, sollte die Standardsortierung ausreichen. Eine andere Möglichkeit ist die Verwendung einer benutzerdefinierten Comparator in Ihrem Tabellenmodell, um die Sortierlogik zu verwalten.

+0

Ok, jetzt ist es ein bisschen klarer, aber ich fürchte, ich vermisse etwas anderes. Ich meine, warum sollte ich 'HashMap ' und nicht eine 'HashMap '? –

+0

Ich habe meinen Code nach dem, was Sie vorgeschlagen haben, aktualisiert. Leider ist die Default 'Sorter' Klasse in' DefaultTableModel' nicht ausreichend, auch wenn ich 'getValueAt()' überschrieben hätte, weil sie immer noch den ursprünglichen numerischen Wert innerhalb des Tabellenmodells berücksichtigt. Deshalb habe ich einen benutzerdefinierten 'Comparator' hinzugefügt, der die vom Benutzer angeklickte Spaltenüberschrift wechselt. –

+0

@LoryLory Es ist Ihre Wahl, ich denke, die Enum Konstante Korrespondent mit dem Wert würde Zugang zu seiner Bezeichnung mit einem einzigen Methodenaufruf führen, und es ist allgemeiner und kann in anderen Teilen Ihrer Anwendung verwendet werden. – STaefi