У меня есть следующая проблема:Как сортировать строки 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 это помогает кто с подобными проблемами ...
почему я никогда не должен хранить JComboBox в моей JTable? – user3133542
Это не то, как работает таблица. Вы храните «данные» в TableModel, и JTable будет отображать данные с помощью соответствующего средства визуализации и редактировать данные с помощью соответствующего редактора. – camickr