简体   繁体   English

如何在JTables中对JComboBox的字符串排序?

[英]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. 我已将JComboBox-Object的每一行插入到JTable的第五列中。 Everything is fine until I want to rowsort the column with setAutoCreateRowSorter(true) . 一切都很好,直到我想使用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: 这是我用于JTable的类:

The TableModel: 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;

        }

    }

The TableCellRenderer: 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;
    }

}

The TableCellEditor: 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

    }

}

I solved the problem by myself : 我自己解决了这个问题:

In the TableModel the getColumnClass() -method for column 5 returns JCombobox.class -object. 在TableModel中,第5列的getColumnClass()方法返回JCombobox.class

In the TableCellEditor there is for each row in the 5th column an own JComboBox -Object and the getCellEditorValue() -method returns the getSelectedItem() of the concerning JComboBox -Object. 在TableCellEditor中,第5列每一行都有一个自己的JComboBox -Object ,而getCellEditorValue() - getCellEditorValue()返回有关JComboBox -Object的getSelectedItem()

So the Jtable has indeed an JComboBox -object ( getValueAt() -method for column 5 from TableModel and getTableCellEditorComponent() -method from TableCellEditor) but the return value is nevertheless a String (getCellEditorValue() from TableCellEditor and getTableCellRendererComponent() -method from TableCellRenderer). 因此,Jtable确实有一个JComboBox -object(TableModel的第5列的getValueAt() -方法和TableCellEditor的getTableCellEditorComponent() -方法),但是返回值仍然是一个字符串(TableCellEditor的getCellEditorValue()和getCellCellRendererComponent getTableCellRendererComponent()方法getTableCellRendererComponent()的TableCellRenderer)。

Hopes this helps anyone with similar problems... 希望这可以帮助任何有类似问题的人...

Why are you creating a custom Comparator? 为什么要创建自定义比较器? The data in the TableModel is String data, not a JCombobox. TableModel中的数据是String数据,而不是JCombobox。 The RowSorter of the table already knows how to sort String data. 该表的RowSorter已经知道如何对String数据进行排序。

You should NEVER actually store a JComboBox in the TableModel. 您永远不应该在TableModel中实际存储JComboBox。 If you are in fact doing this then get rid of it. 如果您实际上正在执行此操作,请摆脱它。

Then get rid of your custom Comparator and it should work fine. 然后摆脱您的自定义比较器,它应该可以正常工作。

If you are trying to use different values for the combo box in different rows then you should try something like: how to add different cell editors for one column in JTable? 如果要为不同行中的组合框使用不同的值,则应尝试类似的操作: 如何为JTable中的一列添加不同的单元格编辑器?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM