问题
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