0

누군가가 도와 줄 수 있습니까? 내가 그것을 최적화하려고 노력할 때까지 그것은 일하고 있었다. .. 저주!JTable 행 분류기 - IllegalArgumentException : 잘못된 SortKey

이 내 테이블 모델 :

class MyTableModel extends DefaultTableModel { 

     private String[] columnNames = {"Last Name","First Name","Next Visit"};  //column header labels 
     Object[][] data = new Object[100][3]; 

     public void reloadJTable(List<Customer> list) { 
      for(int i=0; i< list.size(); i++){ 
       data[i][0] = list.get(i).getLastName(); 
       data[i][1] = list.get(i).getFirstName(); 
       if (list.get(i).getNextVisit()==null) { 
        data[i][2] = "NOT SET"; 
       } else { 
        String date = displayDateFormat.format(list.get(i).getNextVisit().getTime()); 
        data[i][2] = date; 
       } 
       model.addRow(data); 
      } 
     } 

     public void clearJTable() { 
      model.setRowCount(0); 
     } 

     public String getColumnName(int col) { 
      return columnNames[col]; 
     } 

     public Object getValueAt(int row, int col) { 
      return data[row][col]; 
     } 

     /* 
     * JTable uses this method to determine the default renderer/ 
     * editor for each cell. If we didn't implement this method, 
     * then the last column would contain text ("true"/"false"), 
     * rather than a check box. 
     */ 
     public Class getColumnClass(int c) { 
      return getValueAt(0, c).getClass(); 
     } 

     /* 
     * Don't need to implement this method unless your table's 
     * editable. 
     */ 
     public boolean isCellEditable(int row, int col) { 
      //Note that the data/cell address is constant, 
      //no matter where the cell appears onscreen. 
      if (col < 2) { 
       return false; 
      } else { 
       return true; 
      } 
     } 
    } 

이 내가 구현 방법 JTable가 있습니다 :

// these declarations are all private shared across the model 
JTable customerTbl; 
MyTableModel model; 
List<Customer> customers = new ArrayList<Customer>(); 
SimpleDateFormat displayDateFormat = new SimpleDateFormat ("EEE dd-MM-yyyy 'at' hh:mm"); 

//JTable configuration 
model = new MyTableModel(); 
customerTbl = new JTable(model); 
model.reloadJTable(customers); 
customerTbl.setAutoCreateRowSorter(true); //enable row sorters      

DefaultRowSorter sorter = ((DefaultRowSorter)customerTbl.getRowSorter()); //default sort by Last Name 
ArrayList list = new ArrayList(); 
list.add(new RowSorter.SortKey(0, SortOrder.ASCENDING)); 
sorter.setSortKeys(list); //EXCEPTION HERE 
sorter.sort(); 

customerTbl.getColumnModel().getColumn(0).setPreferredWidth(100); //set Last Name column preferred width 
customerTbl.getColumnModel().getColumn(1).setPreferredWidth(80); //set First Name column preferred width 
customerTbl.getColumnModel().getColumn(2).setPreferredWidth(150); //set Last Visit column preferred width 

나는 다음과 같은 예외가 트리거 받고 있어요에 :

sorter.setSortKeys (명부);

Exception in thread "main" java.lang.IllegalArgumentException: Invalid SortKey 
    at javax.swing.DefaultRowSorter.setSortKeys(Unknown Source) 
    at com.vetapp.customer.CustomersGUI.<init>(CustomersGUI.java:128) 
    at com.vetapp.main.VetApp.main(VetApp.java:31) 

나는

+0

내 생각 엔 테이블에 열이 없다고 생각합니다. customerTbl.getColumnCount()는 무엇을 반환합니까? – BevynQ

+0

맞았 어! 0 .. – LePhleg

답변

3

가장 큰 문제는 열 수는 TableModel's 슈퍼 클래스 DefaultTableModel에서 0를 반환하는 것입니다 ...이 제대로 만들어지지 않습니다 TableColumnModel를 함께 할 수있다 생각합니다. 이 방법

@Override 
public int getColumnCount() { 
    return columnNames.length; 
} 

에게 또 다른면을 재정의해야하지만 잠재적으로 치명적인 문제는 getColumnClassTableModel 내 요소의 클래스를 반환한다는 사실이다. 테이블이 비어 있으면 NullPointerException이 표시됩니다. 대신에 String.class과 같은 클래스 리터럴을 사용하십시오.

DefaultTableModel의 경우 별도의 백업 데이터 배열을 유지 관리 할 필요가 없습니다. 이미 자체 데이터 벡터를 가지고 있습니다. 이 방법은 AbstractTableModel을 확장 할 때 사용됩니다.

+0

대신 AbstractTableModel을 확장하는 것이 좋습니다. 또는 적어도 별도의 배열을 유지 관리하는 대신 DefaultTableModel의 기본 데이터 벡터를 사용하십시오. – DannyMo

+0

@damo [RowSorter SortKey가 어떻게 작동하는지 확인하십시오.] (http://stackoverflow.com/questions/16661998/sorting-table-is-wrong-when-the-sort-button-be-pressed-more- 한 번/16664124 # 16664124) – mKorbel

+0

@mKorbel RowSorter의 작동 방식을 이해합니다. Backing 데이터 벡터를 사용하지 않고 DefaultTableModel을 확장하는 것은 좋지 않은 아이디어입니다. 모든 기능을 재정의하려는 경우 확장의 요지는 무엇입니까? DefaultTableModel의 getColumnCount()를 오버라이드 (override)하는 것이 아니라, 대신에 setColumnIdentifiers (Object [] newIdentifiers) 메소드를 호출합니다. 또는 OP가 자신의 데이터를 유지할 강력한 이유가있는 경우 대신 AbstractTableModel을 사용해야합니다. – DannyMo