2013-12-10 1 views
4

Привет Я пытаюсь использовать собственный компаратор только для одного столбца в JTable. Я выполнил это с помощью следующего кода. Проблема в том, что выполнение этого прерывает соответствующий тип для Integer.Как расширить TableRowSorter, чтобы изменить только сравнительный анализатор одного столбца, иметь супер обрабатывать остальные

У меня есть JTable, где классы столбцов: String | Целое | Целое | Boolean | Boolean

Компараторы, которыми я пользуюсь, это эти. Первый использует разделение от How to split a string between letters and digits (or between digits and letters)?.

//compare strings being aware of numbers embedded in the string 
private static Comparator<String> numberAwareCompare = new Comparator<String>() { 
    public int compare(String s1, String s2) { 

     String[] s1Parts = s1.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); 
     String[] s2Parts = s2.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); 

     int i = 0; 
     while(i < s1Parts.length && i < s2Parts.length){ 

      //if parts are the same 
      if(s1Parts[i].compareTo(s2Parts[i]) == 0){ 
       ++i; 
      }else{ 
       try{ 

        int intS1 = Integer.parseInt(s1Parts[i]); 
        int intS2 = Integer.parseInt(s2Parts[i]); 

        //if the parse works 

        int diff = intS1 - intS2; 
        if(diff == 0){ 
         ++i; 
        }else{ 
         return diff; 
        } 
       }catch(Exception ex){ 
        return s1.compareTo(s2); 
       } 
      }//end else 
     }//end while 

      //Handle if one string is a prefix of the other. 
     if(s1.length() < s2.length()){ 
      return -1; 
     }else if(s1.length() > s2.length()){ 
      return 1; 
     }else{ 
      return 0; 
     } 

     return 0; 
    } 
}; 

я продлить TableRowSorter следующим образом:

public class FeatureRowSorter extends TableRowSorter<TableModel>{ 
    public FeatureRowSorter(TableModel tableModel) { 
     super(tableModel); 
     //setComparator(0, numberAwareCompare); 
     //setComparator(1,intCompare); 
     //setComparator(2,intCompare); 
    } 

    @Override 
    public Comparator<?> getComparator(int column){ 
     if(column == 0){ 
      return numberAwareCompare; 
     }else{ 
      return super.getComparator(column); 
     } 
    } 
} 

Это приводит к следующему нежелательному поведению сортировки: enter image description here

Это может быть преодолено путем создания своего рода Integer. Это проблема. Мне не нужно было создавать сортировку для Integer. Если по умолчанию TableRowSorter знает, что класс Integer, почему он не может его создать?

Так я создаю тривиальное Integer сортировщик следующим образом:

//Integer compare, need this to use the custom TableRowSorter 
public static Comparator<Integer> intCompare = new Comparator<Integer>() { 
    @Override 
    public int compare(Integer o1, Integer o2) { 
     return o1 - o2; 
    } 
}; 

Теперь я удаляю метод getComparator выше и добавьте Явно компараторов в правильные столбцы. (Прокомментированный выше код). Это правильное поведение сортировки.

Я добавляю сортировщик строк к таблице со следующим кодом. Моя модель создает новый пользовательский сортировщик строк и отправляет его в JTable представления в объект контроллера.

//In the model, FeatureTableModel extends DefaultTableModel,getClass method implemented correctly  
public FeatureRowSorter getFeatureRowSorter(){ 
     return new FeatureRowSorter(getFeatureTableModel()); 
    } 

Затем добавьте сортировщик в таблицу следующим образом:

view.getFeatureTable().setRowSorter(model.getFeatureRowSorter()); 

Таким образом, вопрос, как бы я сделать это с из того, чтобы реализовать сортировщик Integer? Это похоже на хак, и тот факт, что я реализую компаратор Integer, кажется подозрительным. TableRowSorter знает, что эти столбцы являются Integer из-за метода getClass FeatureTableModel, который реализован правильно. (Никогда не считайте, что один из булевых столбцов не установлен. Я переопределяю этот рендерер).

Любое предложение будет оценено.

UPDATE:

После прочтения ответа Дункана я обнаружил, что не imiplemented GetClass правильно. я имел:

@Override 
    public Class<?> getColumnClass(int column){ 
     if(column == 4){ 
      return Boolean.class; 
     }else if(column == 2){ 
      return Integer.class; 
     }else{ 
      return Object.class; 
     } 
    } 

Я изменил это:

@Override 
    public Class<?> getColumnClass(int column){ 
     if(column == 4){ 
      return Boolean.class; 
     }else if(column == 1 || column == 2){ 
      return Integer.class; 
     }else{ 
      return Object.class; 
     } 
    } 
+0

Хорошо исследованный вопрос. Единственное замечание в том, что [SSCCE] (http://sscce.org) может улучшить ваши шансы на ответ. –

+0

Спасибо Дункан, ты помог мне понять, что ошибка была в моем getClass. Я принял ваш ответ, поскольку он эквивалентен и намного проще. Благодаря! – pbible

ответ

5

на основе быстрого бита тестирования, я достиг желаемых результатов с помощью вызова метода setComparator на экземпляре TableRowSorter. То есть я не создал свой собственный класс, который расширяет TableRowSorter.

JTable table = new JTable(model); 

TableRowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(model); 
table.setRowSorter(rowSorter); 

rowSorter.setComparator(0, new Comparator<String>() { 
    @Override 
    public int compare(String o1, String o2) { 
    // etc. 
    } 

}); 

В моем тесте этот подход не оказал негативного влияния на способность сортировать столбец целых чисел в одной таблице.

Я ценю это не объяснение , почему вы столкнулись с проблемами, но это стоит того, чтобы как можно более упростить работу.