samedi 28 février 2015

How To Sort Strings of JComboBoxes in JTables?



I have following problem:


I've inserted into the 5th column of my JTable for each row an JComboBox-Object. Everything is fine until I want to rowsort the column with setAutoCreateRowSorter(true). In this case im getting following exception:



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


Here are my classes that im using for my JTable:


The 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 String.class;
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;

}

}


The TableRenderer:



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) {
setText((String) ((JComboBox<?>) value).getSelectedItem());
} else {
setText(value.toString());
}

return this;
}

}


And the TableEditor:



public class MyTableCellEditor extends AbstractCellEditor implements
TableCellEditor, ActionListener {

private static final long serialVersionUID = 1L;
private String fieldValue = null;


@Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() instanceof JComboBox<?>) {
JComboBox<?> jComboBox = (JComboBox<?>) event.getSource();
fieldValue = (String) jComboBox.getSelectedItem();
}
}

@Override
public Object getCellEditorValue() {
System.out.println("Editor: getCellEditorValue()");
return fieldValue;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Me");
comboBox.addItem("You");
comboBox.addItem("They");
comboBox.addItem("Us");
comboBox.addItem("We");
comboBox.addActionListener(this);
System.out.println("Editor: getTableCellEditorComponent");
if (value instanceof JComboBox<?>) {
fieldValue = (String) ((JComboBox<?>) value).getSelectedItem();
}

comboBox.setSelectedItem(fieldValue);

return comboBox;
}

}


My idea for that problem was defining an own RowSorter-object and adding it to my JTable-Object (jTable) like this:



private class JComboBoxBoxComparator implements
Comparator<JComboBox<String>> {

@Override
public int compare(JComboBox<String> o1, JComboBox<String> o2) {
return ((String) o1.getSelectedItem()).compareTo((String) o2
.getSelectedItem());
}

}


TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(
jTable.getModel());
sorter.setComparator(5, new JComboBoxBoxComparator());
jTable.setRowSorter(sorter);


Unfortunately this does not have any effect....




Aucun commentaire:

Enregistrer un commentaire