2015-04-29 4 views
1

У меня возникла проблема с попыткой установить редактор ячеек по умолчанию JTable для настраиваемого класса. У меня есть несколько настраиваемых столбцов (числа, строки и логические значения). Для типов номеров я использую свои собственные редакторы ячеек, а для булевых и строковых типов я просто хотел использовать стандартные, предоставляемые классом JTable.JTable устанавливает редактор по умолчанию для настраиваемого класса

У меня есть следующий код в настройках моего стола:

JTable table; 
.... 
table.setDefaultEditor(MyBoolean.class, table.getDefaultEditor(Boolean.class)); 
table.setDefaultRenderer(MyBoolean.class, table.getDefaultRenderer(Boolean.class)); 
table.setDefaultEditor(MyString.class, table.getDefaultEditor(String.class); 
table.setDefaultRenderer(MyString.class, table.getDefaultRenderer(String.class); 

Логический тип работает, как ожидалось, и я могу нажать на tickbox и он включается и выключается. Отображается тип строки, но я не буду редактировать. В моей модели у меня это так, что все столбцы возвращают true для редактируемого.

Если добавить следующее к моей модели:

@Override 
public Class<?> getColumnClass(int columnIndex){ 
    Class<?> clz = columns.get(columnIndex).getClass(); 
    if(clz.isAssignableFrom(MyString.class)){ 
     return String.class; 
    } 
    return clz; 
} 

теперь я могу редактировать строки, как и ожидалось.

Мой вопрос: Почему установка редактора по умолчанию не работает для класса строк, но для булевского класса? Почему у меня должен быть специальный случай в методе getColumnClass в модели?

ответ

1

Я понял, почему он ведет себя так, как я описал первоначально. Это, наконец, щелкнул, когда я посмотрел на метод setValueAt:

@Override 
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
    rows.get(rowIndex).getValues().set(columnIndex, aValue); 
    fireTableCellUpdated(rowIndex, columnIndex); 
} 

и заметил, что Object был экземпляр MyString и результат в ячейку пришел из Object.toString().

Причина MyString вышел в этот методе потому, что GenericEditor в JTable (который охватывает String класса) имеют метод getTableCellEditorComponent который создает java.lang.reflect.Constructor объекта, который используется для создания экземпляра новых экземпляров объектов, разрешенных в данной колонке. MyString класс столбца имел конструктор, который принял String, и, следовательно, он возвратил новый экземпляр столбца MyString в метод setValueAt. Когда я изменил код в getColumnClass (как показано выше), чтобы вернуть String.class, новый экземпляр String был создан, когда редактирование остановлено и оно было передано методу setValueAt и, следовательно, правильно смещено в ячейку.

Определенно узнал много о JTables с этой проблемой.

1

Предполагая, что вы расширяете DefaultTableModel, обратите внимание, что getColumnClass(), унаследованный от AbstractTableModel, "возвращает Object.class независимо от columnIndex." Как отмечено here, Object "отображается меткой, которая отображает строковое значение объекта." Нет редактора по умолчанию для Object. В частности, «Чтобы указать более точные типы столбцов, модель таблицы должна правильно определить метод getColumnClass()».

+0

Я расширяю 'AbstractTableModel' и переопределил метод getColumnClass() как в приведенном выше примере, и он возвращает правильные значения классов, как ожидалось. Проблема в том, что я установил для редактора MyString.class значение «тот же, что и для« String.class », и он не работает. Он работает только тогда, когда я обманываю таблицу, полагая, что столбец, который должен возвращать 'MyString.class', на самом деле является' String.class'. – john

+1

@john эта идея может работать, проблема в остальном вашего кода – mKorbel

+0

См. Реализацию ['getTableCellEditorComponent()'] (http: // grepcode.ком/файл/repository.grepcode.com/Java/корень/JDK/OpenJDK/8-B132/javax/качели/JTable.java). – trashgod