2015-02-28 4 views
1

У меня есть следующая проблема:Как сортировать строки JComboBoxes в JTables?

Я вставил в пятый столбец моего JTable для каждой строки JComboBox-Object. Все в порядке, пока я не хочу сортировать столбцы с setAutoCreateRowSorter(true). В этом случае им получать следующее исключение:

ClassCastException: java.lang.String cannot be cast to javax.swing.JComboBox 

Вот мои классы, которые им с помощью моего JTable:

TableModel:

private class MyTableModel implements TableModel { 

     @Override 
     public void addTableModelListener(TableModelListener l) { 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 

      switch (columnIndex) { 
      case 0: 
       return String.class; 
      case 1: 
       return String.class; 
      case 2: 
       return String.class; 
      case 3: 
       return Number.class; 
      case 4: 
       return Boolean.class; 
      case 5: 
       return JComboBox.class; // modifyed! 

      default: 
       return null; 
      } 

     } 

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

     @Override 
     public String getColumnName(int columnIndex) { 
      return columnNames[columnIndex]; 
     } 

     @Override 
     public int getRowCount() { 
      return data[0].length - 1; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return data[rowIndex][columnIndex]; 

     } 

     @Override 
     public boolean isCellEditable(int rowIndex, int columnIndex) { 
      switch (columnIndex) { 
      case 5: 
       return true; 
      default: 
       return false; 
      } 

     } 

     @Override 
     public void removeTableModelListener(TableModelListener l) { 
     } 

     @Override 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
      data[rowIndex][columnIndex] = aValue; 

     } 

    } 

TableCellRenderer:

public class StringTableCellRenderer extends JLabel implements 
     TableCellRenderer { 

    private static final long serialVersionUID = 1L; 

    public StringTableCellRenderer() { 
     setOpaque(true); 
     setLayout(new BorderLayout()); 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) { 
     Font font = getFont().deriveFont(Font.BOLD, 15); 

     if ((row % 2) == 0) { 
      setBackground(new Color(240, 255, 255)); 
     } else { 
      setBackground(new Color(191, 239, 255)); 
     } 

     if (isSelected) { 
      setBackground(new Color(0, 191, 255)); 
     } 

     setHorizontalAlignment(JLabel.CENTER); 
     setForeground(Color.BLACK); 
     setFont(font); 

     if (value instanceof JComboBox) { 
      System.out.println("Renderer: "+column+" "+row+" "+((JComboBox<?>)value).getSelectedIndex()); 

      setText((String) ((JComboBox<?>) value).getSelectedItem()); 
     } else { 
      setText(value.toString()); 
     } 

     return this; 
    } 

} 

TableCellEditor:

public class MyTableCellEditor extends AbstractCellEditor implements 
     TableCellEditor, ActionListener { 

    private static final long serialVersionUID = 1L; 
    private JComboBox<?>[] comboList = new JComboBox<?>[5]; 
    private int column = 0; 

    @SuppressWarnings("unchecked") 
    public MyTableCellEditor() { 

     for (int i = 0; i < comboList.length; i++) { 
      comboList[i] = new JComboBox<String>(); 
      setComboBox((JComboBox<String>) comboList[i]); 
      comboList[i].setName("ComboBox_" + i); 
     } 

    } 

    public void setComboBox(JComboBox<String> comboBox) { 
     comboBox.addItem("Me"); 
     comboBox.addItem("You"); 
     comboBox.addItem("They"); 
     comboBox.addItem("Us"); 
     comboBox.addItem("We"); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
    } 

    @Override 
    public Object getCellEditorValue() { 
     System.out.println("Editor: getCellEditorValue() "+comboList[column].getSelectedIndex()); 
     if (comboList[column].getSelectedIndex()==-1) { 
      return (String) comboList[column].getItemAt(0); 
     } else { 
      return (String) comboList[column].getSelectedItem(); // returns String not JCombobox! 
     } 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, 
      boolean isSelected, int row, int column) { 

     String fieldValue = null; 
     System.out.println("Editor: getTableCellEditorComponent"); 
     if (value instanceof JComboBox<?>) { 
      fieldValue = (String) ((JComboBox<?>) value).getSelectedItem(); 
     } 
     this.column = column - 1; 
     comboList[column - 1].setSelectedItem(fieldValue); 

     return comboList[column - 1]; // for each row of column 5 an own JComboBox object 

    } 

} 

Я решил проблему сам:

В TableModel на getColumnClass() -метод колонке 5 возвращает JCombobox.class -объекта.

В TableCellEditor есть для каждой строки в 5-м столбца собственный JComboBox -объект и getCellEditorValue() -метода возвращает getSelectedItem() из относительно JComboBox -объекта.

Так JTable имеет действительно JComboBox -объекта (getValueAt() -метода колонке 5 из TableModel и getTableCellEditorComponent() -метода от TableCellEditor), но возвращаемое значение, тем не менее строка (getCellEditorValue() из TableCellEditor и getTableCellRendererComponent() -метод от TableCellRenderer).

Hopes это помогает кто с подобными проблемами ...

ответ

1

Почему вы создаете пользовательский компаратор? Данные в TableModel являются данными String, а не JCombobox. RowSorter таблицы уже знает, как сортировать данные String.

Вы никогда не должны хранить JComboBox в TableModel. Если вы на самом деле делаете это, то избавляйтесь от него.

Тогда избавьтесь от своего пользовательского компаратора, и он должен работать нормально.

Если вы пытаетесь использовать различные значения для поля со списком в разных строках, то вы должны попробовать что-то вроде: how to add different cell editors for one column in JTable?

+0

почему я никогда не должен хранить JComboBox в моей JTable? – user3133542

+0

Это не то, как работает таблица. Вы храните «данные» в TableModel, и JTable будет отображать данные с помощью соответствующего средства визуализации и редактировать данные с помощью соответствующего редактора. – camickr