简体   繁体   English

如何仅在JTable中的特定单元格中设置JComboBox

[英]How to set a JComboBox only in specific cell in a JTable

I want to add a JComboBox only inside a cell who suppose to have a list of values. 我只想在假定具有值列表的单元格内添加JComboBox。 Below is my code but it adds the combo box in all the cells in the column. 下面是我的代码,但它在该列的所有单元格中添加了组合框。 Let me know what's missing in my code to set the combo box only on the selected cell. 让我知道代码中缺少的内容,以便仅在选定的单元格上设置组合框。

     public class PropertiesTableModel extends AbstractTableModel{

 //this method is called to set the value of each cell
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Field field= (Field) fieldList.get(rowIndex);

        if(columnIndex==0){
            String dataType=field.getFieldDef().getDataType();
            return PropertiesPanel.getPpIns().getDataTypeIcon(dataType);
        }

        if(columnIndex==1){
            return field.getFieldDef().getfName();
        }
        else if (columnIndex==2){
             if(field.getFieldDef().getListValue().size()>0){
                 return createValueListCombo(field.getFieldDef().getListValue());
             }

            return field.getDefaultValue();
        }
        else{
            return null;
        }
    }

        public JComboBox createValueListCombo(List<Value> valueList){
        TableColumn valColumn = table.getColumnModel().getColumn(2);
        JComboBox comboBox=new JComboBox();

        for (Value val: valueList) {
            comboBox.addItem(val.getDescription());
        }
        comboBox.setSelectedIndex(0);
        valColumn.setCellEditor(new DefaultCellEditor(comboBox));
        return comboBox;
    }
}

It's really simple and can be done using two ways 这真的很简单,可以通过两种方式完成

First of all your model should notify editor/table that the current cell has list of values. 首先,您的模型应通知编辑器/表当前单元格具有值列表。

public class PropertiesTableModel extends AbstractTableModel {
     @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        // previous stuff
        if (columnIndex == 2) {
            // return the actually selected value, 
            // not the first value of the list!
            // also the values changed by setValueAt() must be considered.
            return null; // implement it!
        }
    }

    public List<Object> getPossibleValues(int row, int column) {
        // this method should return possible values to select.
        // if cell has no possible values and should be editeb 
        // by a text field this methos should return null
        if (column == 2) {
             Field field= (Field) fieldList.get(rowIndex);
             if (field.getFieldDef().getListValue().size() > 0) {
                 return field.getFieldDef().getListValue();
             }
             return null; // probably something else for non-list values
         }
    }

    public void setValueAt(int row, int column) {
        // you need to store the value chosen by the user
    }
}

1) Override the method public TableCellEditor getCellEditor(int row, int column) in JTable 1)重写JTable的方法public TableCellEditor getCellEditor(int row, int column)

public TableCellEditor getCellEditor(int row, int column) {
    PropertiesTableModel model = (PropertiesTableModel) getModel();
    List<Object> values = model.getPossibleValues(row, column);
    if (values != null) {
       return new DefaultCellEditor(new JComboBox(values.toArray()));
    } else {
       return super.getCellEditor(row, column);
    }
}

2) You can create a custom editor which delegates all calls to one of two (or more) editors depended on the currently edited cell. 2)您可以创建一个自定义编辑器,该编辑器将所有调用委派给两个(或多个)编辑器中的一个,具体取决于当前编辑的单元格。

public class CellEditorMulticaster implements TableCellEditor {
    private DefaultTableCellEditor textEditor;
    private DefaultTableCellEditor currentEditor;

    public CellEditorMulticaster() {
        firstEditor = new DefaultTableCellEditor(new JTextField());
    }

    Component getTableCellEditorComponent(JTable table, Object value,
                                      boolean isSelected,
                                      int row, int column) {
        PropertiesTableModel model = (PropertiesTableModel) table.getModel();
        List<Object> values = model.getPossibleValues(row, column);
        if (values != null) {
            currentEditor = new DefaultCellEditor(new JComboBox(values.toArray()));
        } else {
            currentEditor = textEditor;
        }
        return currentEditor.getTableCellEditorComponent(table, value,
               isSelected, row, column);
    }

    public Object getCellEditorValue() {
        return currentEditor.getCellEditorValue();
    }

    public boolean isCellEditable(EventObject anEvent) {
        JTable table = (JTable) anEvent.getSource;
        int row, col;
        if (anEvent instanceof MouseEvent) {
            MouseEvent evt = (MouseEvent) anEvent;
            row = table.rowAtPoint(evt.getPoint());
            col = table.columnAtPoint(evt.getPoint());
        } else {
            row = table.getSelectedRow();
            col = table.getSelectedColumn();
        }
        PropertiesTableModel model = (PropertiesTableModel) table.getModel();
        List<Object> values = model.getPossibleValues(row, column);
        if (values != null) {
            return true;
        } else {
            return textEditor.isCellEditable(anEvent);
        }
    }

    public boolean shouldSelectCell(EventObject anEvent) {
        return true;
    }

    public boolean stopCellEditing() {
        return currentEditor.stopCellEditing();
    }

    public void  cancelCellEditing() {
        currentEditor.cancelCellEditing();
    }

    // same pattern for another methods (delegate to currentEditor)
}   

i am sorry that i not valid to add comment , but i have to report a problem for sergiy's answer . 抱歉,我没有必要添加评论,但我必须报告一个关于Sergiy答案的问题。

it's for the step 1 : 1) Override the method public TableCellEditor getCellEditor(int row, int column) in JTable 这是针对步骤1的:1)重写JTable中的方法public TableCellEditor getCellEditor(int row,int column)

i found each time i click the comboBox , this code will create a new combobox as a new cell editor . 我每次单击comboBox时都会发现,此代码将创建一个新的combobox作为新的单元格编辑器。 and my code will be crash after i clicked 2-3 times as the Index out of bounds for length. 当我点击2-3次作为索引超出长度时,我的代码将崩溃。

i am fully confuse about this , hope can get the answer here . 我对此完全感到困惑,希望能在这里得到答案。

my code is : 我的代码是:

@Override
    public TableCellEditor getCellEditor(int row, int column) {
        TableModel model = (TableModel) getModel();
        String[] values = model.getPossibleValues(row, column);
        if (values != null) {
            JComboBox<String> comboBox = new JComboBox<String>(values);
            comboBox.addActionListener((e)->{
                model.setValueAt(row, column, comboBox.getSelectedItem());
            });
            return new DefaultCellEditor(comboBox);
        } else {
            return super.getCellEditor(row, column);            
        }
    }

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

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