JTable alway can not get correct rowIndex for inner ComboBox

删除回忆录丶 提交于 2019-12-24 14:17:01

问题


I have a JTable which its one column cell is JComboBox. But when try to get row count when click the table JComboBox cell, I found the row index always return error value (alway is the last click row index).

public class TableComboBoxTest extends JFrame {

    private JTable table;
    private DefaultTableModel tableModel;
    private Object[][] tableCells;
    private final String[] TABLE_COLUMNS = {"No.1"};
    private final String[] YES_NO_SELECTION = {"Yes", "No"};

    public TableComboBoxTest() {
        Container pane = getContentPane();
        pane.setLayout(new BorderLayout());
        tableModel = new DefaultTableModel(tableCells, TABLE_COLUMNS);

        table = new JTable(tableModel);

        DefaultCellEditor cellEditor = null;

        JComboBox selA = new JComboBox(YES_NO_SELECTION);
        cellEditor = new DefaultCellEditor(selA);
        cellEditor.setClickCountToStart(1);
        table.getColumn(TABLE_COLUMNS[0]).setCellEditor(cellEditor);

        JScrollPane jsp = new JScrollPane();
        jsp.getViewport().add(table, null);
        pane.add(jsp, BorderLayout.CENTER);

        TableCellEditor tce = null;
        addRow("Yes");
        outputDefaultSelection(0, 0);

        addRow("No");
        outputDefaultSelection(1, 0);

        System.out.println("");

        selA.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    JComboBox cb = (JComboBox) e.getSource();
                    String sel = (String) cb.getSelectedItem();
                    int rowIndex = table.getSelectedRow();
                    rowIndex = table.convertRowIndexToModel(rowIndex);

                    if (rowIndex == -1) {
                        return;
                    }

                    outputDefaultSelection(rowIndex, 0);
                    System.out.println("Select: " + sel + " at " + rowIndex);
                }
            }
        });
    }

    private void addRow(String v1) {
        Vector<String> vec = new Vector<String>();
        vec.add(v1);

        tableModel.addRow(vec);
        tableModel.fireTableDataChanged();
    }

    private void outputDefaultSelection(int row, int col) {
        TableCellEditor tce = table.getCellEditor(row, col);
        System.out.println("Default " + row + "-" + col + " Selection: " + tce.getCellEditorValue());
        System.out.println("Default " + row + "-" + col + " Value: " + table.getModel().getValueAt(row, col));
    }

    public static void main(String[] args) {
        TableComboBoxTest stt = new TableComboBoxTest();
        stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        stt.setSize(200, 100);
        stt.setVisible(true);
    }
}
Default 0-0 Selection: Yes
Default 0-0 Value: Yes
Default 1-0 Selection: Yes
Default 1-0 Value: No*

When Click on first row and select "Yes", no change event trigger. When Click on second row, change event trigger! and row number is wrong: 0

Default 0-0 Selection: No
Default 0-0 Value: Yes
Select: No at 0*

When continue to click on first row, change event trigger! and row number is wrong: 1

Default 1-0 Selection: Yes
Default 1-0 Value: No
Select: Yes at 1

How can I get correct clicking cell number?

And for the itemStateChanged process, I also found if cell set value is same with default column value ("Yes"), when click it event will not be trigger. But if cell set value to "No", click it will cause change event. That means model data is different with default selected data. How to make them consistent?

Thanks~


回答1:


That means model data is different with default selected data. How to make them consistent?

It just means that the model has not yet been updated with the newly selected value from the combo box.

This can be demonstrated by using the following:

final String sel = (String) cb.getSelectedItem();
final int rowIndex = table.convertRowIndexToModel(table.getSelectedRow());

if (rowIndex == -1) {
    return;
}

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        outputDefaultSelection(rowIndex, 0);
        System.out.println("Select: " + sel + " at " + rowIndex);
    }
});

Now, the display code will be added to the end of the Event Dispatch Thread, which means it will be executed after all other events are finished executing so the TableModel will now be updated.

However, that is not the best solution. If you want to know when data has been changed in a cell then add a TableModelListener to the TableModel. Don't use an ItemListener.



来源:https://stackoverflow.com/questions/18975507/jtable-alway-can-not-get-correct-rowindex-for-inner-combobox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!