簡體   English   中英

如何僅在JTable中的特定單元格中設置JComboBox

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

我只想在假定具有值列表的單元格內添加JComboBox。 下面是我的代碼,但它在該列的所有單元格中添加了組合框。 讓我知道代碼中缺少的內容,以便僅在選定的單元格上設置組合框。

     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;
    }
}

這真的很簡單,可以通過兩種方式完成

首先,您的模型應通知編輯器/表當前單元格具有值列表。

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)重寫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)您可以創建一個自定義編輯器,該編輯器將所有調用委派給兩個(或多個)編輯器中的一個,具體取決於當前編輯的單元格。

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)
}   

抱歉,我沒有必要添加評論,但我必須報告一個關於Sergiy答案的問題。

這是針對步驟1的:1)重寫JTable中的方法public TableCellEditor getCellEditor(int row,int column)

我每次單擊comboBox時都會發現,此代碼將創建一個新的combobox作為新的單元格編輯器。 當我點擊2-3次作為索引超出長度時,我的代碼將崩潰。

我對此完全感到困惑,希望能在這里得到答案。

我的代碼是:

@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