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); } }
关键修改说明:
- 处理ComboBox返回-1的情况:在
setValue中检查comboIndex的有效性,当索引小于0或超出数组范围时,将值设为空字符串,避免数组越界。 - 基于当前激活的编辑器处理值:不再依赖元素原来的
str[1]判断逻辑,而是直接获取当前正在使用的编辑器类型,这样无论用户在编辑过程中选择了什么选项,都能正确处理输入值。 - 保持编辑器切换逻辑一致:当值为空或不匹配下拉列表中的非空项时,自动切换到TextCellEditor,确保用户可以自由输入自定义内容。
另外,你可以考虑把names数组的第一个空项改成空字符串"",这样逻辑更统一,避免空格和空字符串的混淆,但这取决于你的业务需求。
内容的提问来源于stack exchange,提问作者khunnie
相关产品推荐
相关产品推荐

