You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EditingSupport中ComboBoxCellEditor切换异常:数组越界问题求助

解决ComboBoxCellEditor切换TextCellEditor时的ArrayIndexOutOfBoundsException问题

我看了你的代码和堆栈追踪,这个-1索引的错误是因为ComboBoxCellEditor在用户未选择有效选项(比如直接关闭编辑器,或者选择空项时可能返回-1)时,会返回-1作为输入值,而你的代码没有处理这种情况,直接用这个索引去访问names数组,导致越界。另外,当前setValue方法的判断逻辑依赖于元素原来的值,而不是用户实际使用的编辑器类型,这也会导致逻辑错误。

下面是修改后的代码,我会标注关键修改点:

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;

public class SecondColEdittingSupport extends EditingSupport {
    private final TableViewer viewer;
    private final CellEditor comboEditor;
    private final CellEditor textEditor;
    Logger logger = Logger.getLogger(this.getClass());
    public static String[] names = {" ", "SMALLINT ", "INTEGER", "BIGINT", "DECIMAL", "NUMERIC", "REAL", "TIMESTAMP", "VARCHAR", "CHAR", "TEXT"};

    public SecondColEdittingSupport(TableViewer viewer) {
        super(viewer);
        this.viewer = viewer;
        comboEditor = new ComboBoxCellEditor(viewer.getTable(), names);
        textEditor = new TextCellEditor(viewer.getTable());
    }

    private int getNameIndex(String name) {
        for (int i = 1; i < names.length; i++) {
            if (names[i].equals(name)) {
                return i;
            }
        }
        return 0;
    }

    @Override
    protected CellEditor getCellEditor(Object element) {
        String[] str = (String[]) element;
        // 如果当前值匹配下拉列表中的非空项,用ComboBox编辑器;否则用Text编辑器
        return getNameIndex(str[1]) != 0 ? comboEditor : textEditor;
    }

    @Override
    protected boolean canEdit(Object element) {
        return true;
    }

    @Override
    protected Object getValue(Object element) {
        String[] str = (String[]) element;
        int index = getNameIndex(str[1]);
        // 如果是下拉列表中的项,返回索引;否则返回文本值
        return index != 0 ? index : str[1];
    }

    @Override
    protected void setValue(Object element, Object userInputValue) {
        String[] str = (String[]) element;
        
        // 先判断当前使用的编辑器类型,而不是依赖元素原来的值
        CellEditor activeEditor = getViewer().getCellEditor();
        
        if (activeEditor == comboEditor) {
            Integer comboIndex = (Integer) userInputValue;
            // 处理ComboBox返回-1的情况(用户未选择或取消编辑)
            if (comboIndex >= 0 && comboIndex < names.length) {
                str[1] = names[comboIndex];
            } else {
                // 当索引无效时,设置为空字符串,后续会切换到Text编辑器
                str[1] = "";
            }
        } else if (activeEditor == textEditor) {
            str[1] = String.valueOf(userInputValue);
        }
        
        viewer.update(element, null);
    }
}

关键修改说明:

  1. 处理ComboBox返回-1的情况:在setValue中检查comboIndex的有效性,当索引小于0或超出数组范围时,将值设为空字符串,避免数组越界。
  2. 基于当前激活的编辑器处理值:不再依赖元素原来的str[1]判断逻辑,而是直接获取当前正在使用的编辑器类型,这样无论用户在编辑过程中选择了什么选项,都能正确处理输入值。
  3. 保持编辑器切换逻辑一致:当值为空或不匹配下拉列表中的非空项时,自动切换到TextCellEditor,确保用户可以自由输入自定义内容。

另外,你可以考虑把names数组的第一个空项改成空字符串"",这样逻辑更统一,避免空格和空字符串的混淆,但这取决于你的业务需求。

内容的提问来源于stack exchange,提问作者khunnie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:08:10