2017-11-16 7 views
0

의 열 I에 따라 여러 열을 다음과 같이 열거의 숫자가 포함 JTable로이 순서 : 그래서자바 : JTable로는 열거

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

, 나는 테이블 모델의 방법 getValueAt()을 통해 반복 오버라이드 (override) 할 필요 enum 값을 사용하여 데이터가 들어있는 데이터베이스에서 숫자 값이 저장되는 것처럼 각 행의 해당 String을 디코딩하고 반환합니다. 이제 사용자가 해당 헤더 열을 클릭하면 숫자 값에 따라 행이 정렬되지만 알파벳순으로 정렬하고 싶습니다. 테이블 모델의 메소드 sort()을 오버라이드해야합니까? 설명을 비효율적으로 만들기 위해 열거 형 값을 통해 여러 번 반복하지 않습니까? 테이블 렌더링 속도가 느려 집니까? 각 행에 대해 열거 값을 통해 반복을 방지하기 위해

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

답변

1

, 당신은 만들 수 있습니다 :

UPDATE는

이 내 DefaultTableModelField을 확장 내부 STaefi이 어떤 제안에 다음과 같은 해결책이 될 수 static final HashMap<Integer,IMPORT_CONF_OPERATION_RESULT>은 값의 맵을 해당 레이블에 캐시하고이를 열거 형 내부의 정적 블록에서 초기화합니다. 그런 다음 public static String getLabelByValue(int value)을 사용하여 캐시를 사용하고 매번 레이블을 찾으려면 O(n)을 피하십시오.

정렬 순서 및 정렬 동작을 제어하려면 TableRowSorter 이후에 수행 할 수 있지만 getValueAt을 기본 정렬 방식으로 재정의 한 경우 기본 정렬로 충분해야합니다. 다른 방법은 테이블 모델에 사용자 정의 Comparator을 사용하여 정렬 논리를 관리하는 것입니다.

+0

좋아, 이제 조금 더 명확 해지 겠지만, 나는 다른 것을 놓치고있어. 내 말은 왜 HashMap 및'HashMap '을 사용해야하지 않는가? –

+0

제안한대로 코드를 업데이트했습니다. 불행하게도'DefaultTableModel' 내부의 디폴트'Sorter' 클래스는'getValueAt()'를 오버라이드 했더라도 여전히 테이블 모델 안에 저장되어있는 원래 숫자 값을 고려하기 때문에 충분하지 않습니다. 그래서 사용자가 클릭 한 열 머리글을 전환하는 사용자 지정 Comparator를 추가했습니다. –

+0

@LoryLory 그것은 당신의 선택입니다, 나는 열거 형 상수 값을 갖는 것이 단일 메소드 호출로 라벨에 접근하는 결과를 초래할 것이라고 생각합니다. 그리고 더 일반적이고 여러분의 다른 부분에서 사용될 수 있습니다. – STaefi