Java 在JTable中设置JCombobox的SelectedItem

Java 在JTable中设置JCombobox的SelectedItem,java,swing,jtable,jcombobox,Java,Swing,Jtable,Jcombobox,我有一个JTable,我在三个不同的列中添加了三个jcombox。 现在,我想为我拥有的每一行设置所选项目。问题是,我需要每一行的ID来执行此操作。 所以我尝试了不同的监听器,最好的结果是使用FocusListener,但是我总是要先单击行,然后单击JComboBox,这很费劲。 以下是一个例子: JTable table = new JTable(); Vector<ArrayList<Object>> data = new Vector<ArrayLis

我有一个JTable,我在三个不同的列中添加了三个jcombox。 现在,我想为我拥有的每一行设置所选项目。问题是,我需要每一行的ID来执行此操作。 所以我尝试了不同的监听器,最好的结果是使用FocusListener,但是我总是要先单击行,然后单击JComboBox,这很费劲。 以下是一个例子:

JTable table = new JTable();
    Vector<ArrayList<Object>> data = new Vector<ArrayList<Object>>();
    for (int i = 0; i < 5; i++)
    {
        ArrayList<Object> object = new ArrayList<Object>();
        object.add(i);
        object.add("name");
        object.add(i+1);
        object.add(i+1);
        object.add(i+1);
        data.add(object);
    }
    DefaultTableModel tableModel = new DefaultTableModel() {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @Override
        public boolean isCellEditable(int row, int column) {
            if (column < 2)
                return false;
            return true;
        }
    };
    tableModel.setColumnIdentifiers(new String[] {"ID", "Name", "OK", "Other", "Error"});
    tableModel.addTableModelListener(new TableModelListener()
    {

        @Override
        public void tableChanged(TableModelEvent e)
        {
            if (e.getType() == TableModelEvent.UPDATE)
            {
                int row = e.getFirstRow();
                int column = e.getColumn();
                TableModel table_model = (TableModel) e.getSource();
                ArrayList<Object> changed_data = (ArrayList<Object>) table_model.getValueAt(row, column);
                String row_id = String.valueOf(table_model.getValueAt(row, 0));
                for (ArrayList<Object> list : data)
                {
                    String compare_id = String.valueOf(list.get(0));
                    if (row_id.equals(compare_id))
                    {
                        list.set(column, String.valueOf(changed_data.get(0)));
                        for (int i = table_model.getRowCount()-1; i >= 0 ; i--)
                        {
                            tableModel.removeRow(i);
                        }

                        for (ArrayList<Object> object : data)
                        {
                            Vector<String> vector = new Vector<String>();
                            vector.addElement(String.valueOf(object.get(0)));
                            vector.addElement(String.valueOf(object.get(1)));
                            vector.addElement(String.valueOf(object.get(2)));
                            vector.addElement(String.valueOf(object.get(3)));
                            vector.addElement(String.valueOf(object.get(4)));
                            tableModel.addRow(vector);
                        }

                        TableColumn column_ok = table.getColumnModel().getColumn(2);
                        TableColumn column_other = table.getColumnModel().getColumn(3);
                        TableColumn column_error = table.getColumnModel().getColumn(4);

                        JComboBox<ArrayList<Object>> combobox_ok = new JComboBox<ArrayList<Object>>(data);
                        JComboBox<ArrayList<Object>> combobox_other = new JComboBox<ArrayList<Object>>(data);
                        JComboBox<ArrayList<Object>> combobox_error = new JComboBox<ArrayList<Object>>(data);

                        column_ok.setCellEditor(new DefaultCellEditor(combobox_ok));
                        column_other.setCellEditor(new DefaultCellEditor(combobox_other));
                        column_error.setCellEditor(new DefaultCellEditor(combobox_error));
                        break;
                    }
                }
            }
        }
    });
    table.setModel(tableModel);
    for (ArrayList<Object> object : data)
    {
        Vector<String> vector = new Vector<String>();
        vector.addElement(String.valueOf(object.get(0)));
        vector.addElement(String.valueOf(object.get(1)));
        vector.addElement(String.valueOf(object.get(2)));
        vector.addElement(String.valueOf(object.get(3)));
        vector.addElement(String.valueOf(object.get(4)));
        tableModel.addRow(vector);
    }

    TableColumn column_ok = table.getColumnModel().getColumn(2);
    TableColumn column_other = table.getColumnModel().getColumn(3);
    TableColumn column_error = table.getColumnModel().getColumn(4);

    JComboBox<ArrayList<Object>> combobox_ok = new JComboBox<ArrayList<Object>>(data);
    JComboBox<ArrayList<Object>> combobox_other = new JComboBox<ArrayList<Object>>(data);
    JComboBox<ArrayList<Object>> combobox_error = new JComboBox<ArrayList<Object>>(data);

    column_ok.setCellEditor(new DefaultCellEditor(combobox_ok));
    column_other.setCellEditor(new DefaultCellEditor(combobox_other));
    column_error.setCellEditor(new DefaultCellEditor(combobox_error));

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.getViewport().add(table);

    JFrame frame = new JFrame();
    frame.add(scrollPane);
    frame.setSize(400, 200);
    frame.setVisible(true);
JTable table=新的JTable();
向量数据=新向量();
对于(int i=0;i<5;i++)
{
ArrayList对象=新的ArrayList();
对象.添加(i);
对象。添加(“名称”);
对象。添加(i+1);
对象。添加(i+1);
对象。添加(i+1);
数据。添加(对象);
}
DefaultTableModel tableModel=新的DefaultTableModel(){
/**
* 
*/
私有静态最终长serialVersionUID=1L;
@凌驾
公共布尔值可编辑(int行,int列){
如果(列<2)
返回false;
返回true;
}
};
setColumnIdentifiers(新字符串[]{“ID”、“Name”、“OK”、“Other”、“Error”});
tableModel.addTableModelListener(新的TableModelListener()
{
@凌驾
公共作废表已更改(TableModelEvent e)
{
if(e.getType()==TableModelEvent.UPDATE)
{
int row=e.getFirstRow();
int column=e.getColumn();
TableModel table_model=(TableModel)e.getSource();
ArrayList changed_data=(ArrayList)table_model.getValueAt(行、列);
String row_id=String.valueOf(table_model.getValueAt(row,0));
对于(ArrayList:数据)
{
字符串比较_id=String.valueOf(list.get(0));
if(行id等于(比较id))
{
list.set(column,String.valueOf(changed_data.get(0));
对于(int i=table_model.getRowCount()-1;i>=0;i--)
{
tableModel.removeRow(i);
}
for(ArrayList对象:数据)
{
向量=新向量();
vector.addElement(String.valueOf(object.get(0));
vector.addElement(String.valueOf(object.get(1));
vector.addElement(String.valueOf(object.get(2));
vector.addElement(String.valueOf(object.get(3));
vector.addElement(String.valueOf(object.get(4));
tableModel.addRow(向量);
}
TableColumn\u ok=table.getColumnModel().getColumn(2);
TableColumn column_other=table.getColumnModel().getColumn(3);
TableColumn column_error=table.getColumnModel().getColumn(4);
JComboBox组合框_ok=新的JComboBox(数据);
JComboBox combobox_other=新的JComboBox(数据);
JComboBox combobox_error=新的JComboBox(数据);
列_ok.setCellEditor(新的DefaultCellEditor(组合框_ok));
column_other.setCellEditor(新的DefaultCellEditor(combobox_other));
列_error.setCellEditor(新的DefaultCellEditor(组合框_error));
打破
}
}
}
}
});
table.setModel(tableModel);
for(ArrayList对象:数据)
{
向量=新向量();
vector.addElement(String.valueOf(object.get(0));
vector.addElement(String.valueOf(object.get(1));
vector.addElement(String.valueOf(object.get(2));
vector.addElement(String.valueOf(object.get(3));
vector.addElement(String.valueOf(object.get(4));
tableModel.addRow(向量);
}
TableColumn\u ok=table.getColumnModel().getColumn(2);
TableColumn column_other=table.getColumnModel().getColumn(3);
TableColumn column_error=table.getColumnModel().getColumn(4);
JComboBox组合框_ok=新的JComboBox(数据);
JComboBox combobox_other=新的JComboBox(数据);
JComboBox combobox_error=新的JComboBox(数据);
列_ok.setCellEditor(新的DefaultCellEditor(组合框_ok));
column_other.setCellEditor(新的DefaultCellEditor(combobox_other));
列_error.setCellEditor(新的DefaultCellEditor(组合框_error));
JScrollPane scrollPane=新的JScrollPane();
scrollPane.getViewport().add(表);
JFrame=新JFrame();
frame.add(滚动窗格);
框架。设置尺寸(400200);
frame.setVisible(true);
现在,在第一行第三列(“OK”)中,您可以在JComboBox中选择代表一行的不同条目。因此,一行有三个JComboxes引用另一行。 如果您在这样的JComboBox中单击,您会注意到它总是选择第一个条目,而不是单击之前看到的带有数字的条目

也许现在你明白我想做什么了

如果在这样一个
JComboBox
中单击,您会注意到它总是选择第一个条目,而不是单击之前看到的带有数字的条目

下面的简化完整示例将重点关注问题的这一方面,当单元格编辑器处于活动状态时,始终显示选定的条目。您可以根据需要替换组合以显示不同的结果。另外,

  • 重写
    getPreferredScrollableViewportSize()
    以建立表的所需大小

  • 尽可能使用类型参数;如有需要,重写getColumnClass(),例如

  • 覆盖相关数据的
    getValueAt()
    ,如图和所示

  • 请注意简化的含义
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.util.Arrays;
    import java.util.Vector;
    import javax.swing.DefaultCellEditor;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableColumn;
    
    /**
     * @see https://stackoverflow.com/q/39993746/230513
     */
    public class TableComboTest {
    
        private Vector<Vector<String>> createData() {
            Vector<Vector<String>> data = new Vector<Vector<String>>();
            for (int i = 0; i < 5; i++) {
                Vector<String> rowVector = new Vector<String>();
                rowVector.add(String.valueOf(i));
                rowVector.add("name");
                rowVector.add(String.valueOf(i + 1));
                rowVector.add(String.valueOf(i + 1));
                rowVector.add(String.valueOf(i + 1));
                data.add(rowVector);
            }
            return data;
        }
    
        private void display() {
            Vector<Vector<String>> data = createData();
            Vector<String> names = new Vector<>(Arrays.asList("ID", "Name", "OK", "Other", "Error"));
            DefaultTableModel tableModel = new DefaultTableModel(data, names) {
    
                @Override
                public boolean isCellEditable(int row, int column) {
                    return column > 1;
                }
            };
            JTable table = new JTable(tableModel) {
                @Override
                public Dimension getPreferredScrollableViewportSize() {
                    return new Dimension(getPreferredSize().width, getRowHeight() * 4);
                }
            };
    
            TableColumn column_ok = table.getColumnModel().getColumn(2);
            TableColumn column_other = table.getColumnModel().getColumn(3);
            TableColumn column_error = table.getColumnModel().getColumn(4);
    
            String[] choices = new String[]{"1", "2", "3", "4", "5"};
            JComboBox<String> combobox_ok = new JComboBox<>(choices);
            JComboBox<String> combobox_other = new JComboBox<String>(choices);
            JComboBox<String> combobox_error = new JComboBox<String>(choices);
    
            column_ok.setCellEditor(new DefaultCellEditor(combobox_ok));
            column_other.setCellEditor(new DefaultCellEditor(combobox_other));
            column_error.setCellEditor(new DefaultCellEditor(combobox_error));
    
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new JScrollPane(table));
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new TableComboTest()::display);
        }
    }