JComboBox 作为 Jtable CellEditor 与 Overriden stopCellEditing 修改错误的表格单元格 [英] JComboBox as Jtable CellEditor with Overriden stopCellEditing modifies wrong table cell
问题描述
我有一个带有自定义 TableModel 的自定义 JTable,使用 JComboBox 作为单元格编辑器.ComboBox 也有一个自定义的 ComboBoxModelComboBox 模型包含多个字段,这些字段将用于更新 JTable 背后的数据,然后更新数据库.
I have a custom JTable with a custom TableModel using a JComboBox as a cell editor. The ComboBox also has a custom ComboBoxModel The ComboBox model holds multiple fields that will be used to update the data behind the JTable and afterwards update a database.
下面是一个简单的例子来展示我遇到的问题.重现步骤:
The following is a simple example to show the problem I am encountering. Steps to reproduce:
- 点击一个单元格
- 从组合框下拉列表中选择一个值
- 点击不同的单元格
- 点击第一个选定的单元格
第二个单元格将获取第一个单元格的值.
The second cell will get the value from the first one.
为什么会这样?为什么 ComboBox 模型在 stopCellEditing 存在之前发生变化?
Why is this happening? Why does the ComboBox model change before stopCellEditing exists?
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class TestComboCellEditor {
public static void main(String[] args) {
TestComboCellEditor test = new TestComboCellEditor();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create and add a tabbed pane to the frame
JTabbedPane tabbedPane = new JTabbedPane();
frame.getContentPane().add(tabbedPane);
//create a table and add it to a scroll pane in a new tab
final JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
JScrollPane scrollPane = new JScrollPane(table);
tabbedPane.addTab("test", scrollPane);
// create a simple JComboBox and set is as table cell editor on column A
Object[] comboElements = {"aaaaa1", "aaaaaa2", "b"};
final JComboBox comboBox = new JComboBox(comboElements);
comboBox.setEditable(true);
table.getColumn("A").setCellEditor(new DefaultCellEditor(comboBox) {
@Override
public boolean stopCellEditing() {
if (comboBox.isEditable()) {
DefaultComboBoxModel comboModel = (DefaultComboBoxModel) comboBox.getModel();
String selectedItem = (String) comboModel.getSelectedItem();
int selectedIndex = comboModel.getIndexOf(selectedItem);
if (!(selectedIndex == -1)) {
// the selected item exists as an Option inside the ComboBox
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
tableModel.setValueAt(selectedItem, selectedRow, selectedColumn);
} else if (selectedItem != null) {
// missing code - adding new info to a custom JComboBox model and to alter info inside a custom table model
}
}
return super.stopCellEditing();
}
});
// pack and show frame
frame.pack();
frame.setVisible(true);
}
}
推荐答案
这是一种将所有代码保存在编辑器中的方法:
Here is an approach that keeps all the code in the editor:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class TestComboCellEditor {
public static void main(String[] args) {
TestComboCellEditor test = new TestComboCellEditor();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create and add a tabbed pane to the frame
JTabbedPane tabbedPane = new JTabbedPane();
frame.getContentPane().add(tabbedPane);
//create a table and add it to a scroll pane in a new tab
final JTable table = new JTable(new DefaultTableModel(new Object[]{"A", "B"}, 5));
JScrollPane scrollPane = new JScrollPane(table);
tabbedPane.addTab("test", scrollPane);
// create a simple JComboBox and set is as table cell editor on column A
Object[] comboElements = {"aaaaa1", "aaaaaa2", "b"};
final JComboBox comboBox = new JComboBox(comboElements);
comboBox.setEditable(true);
table.getColumn("A").setCellEditor(new DefaultCellEditor(comboBox)
{
private Object originalValue;
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
originalValue = value;
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
@Override
public boolean stopCellEditing()
{
JComboBox comboBox = (JComboBox)getComponent();
DefaultComboBoxModel comboModel = (DefaultComboBoxModel) comboBox.getModel();
Object editingValue = getCellEditorValue();
// Needed because your TableModel is empty
if (editingValue == null)
return super.stopCellEditing();
int selectedIndex = comboModel.getIndexOf(editingValue);
// Selecting item from model
if (! (selectedIndex == -1))
return super.stopCellEditing();
// Confirm addition of new value
int result = JOptionPane.showConfirmDialog(
comboBox.getParent(),
"Add (" + editingValue + ") to table?",
"Update Model",
JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION)
{
comboBox.addItem(editingValue);
return super.stopCellEditing();
}
else
{
comboBox.removeItem(editingValue);
comboBox.setSelectedItem(originalValue);
return false;
}
}
});
// pack and show frame
frame.pack();
frame.setVisible(true);
}
}
这篇关于JComboBox 作为 Jtable CellEditor 与 Overriden stopCellEditing 修改错误的表格单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!