0
votes

I want to make the ComboBoxCellEditor editable if user selects an " " item. I tried to use two CellEditor, one is TextCellEditor, one is ComboBoxCellEditor. And if user select " " item, the CellEditor will switch to TextCellEditor. But it doesn't work. Because the comboIndex had a ArrayOutOfBoundException. Can anyone help me to modify my code? The code of the original EditingSupport shows below:

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 < SecondColEdittingSupport.names.length; i++) {
            if (SecondColEdittingSupport.names[i].equals(name))
                return i;
        }
        return 0;
    }

    @Override
    protected CellEditor getCellEditor(Object element) {
        String[] str = (String[]) element;
        if (getNameIndex(str[1]) != 0) {
            return comboEditor;
        }
        return textEditor;
    }

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

    @Override
    protected Object getValue(Object element) {
        String[] str = (String[]) element;
        if (getNameIndex(str[1]) != 0) {
            return getNameIndex(str[1]);
        }
        return  str[1];
    }

    @Override
    protected void setValue(Object element, Object userInputValue) {
        String[] str = (String[]) element;
        if (getNameIndex(str[1]) != 0) {
            Integer comboIndex = (Integer) userInputValue;
            str[1] = SecondColEdittingSupport.names[comboIndex];
        } else {
            str[1] = String.valueOf(userInputValue);
        }
        viewer.update(element, null);
    }

}

The stack trace shows below:

java.lang.ArrayIndexOutOfBoundsException: -1 at com.highgo.admin.migrator.ui.SecondColEdittingSupport.setValue(SecondColEdittingSupport.java:77) at org.eclipse.jface.viewers.EditingSupport.saveCellEditorValue(EditingSupport.java:113) at org.eclipse.jface.viewers.ColumnViewerEditor.saveEditorValue(ColumnViewerEditor.java:433) at org.eclipse.jface.viewers.ColumnViewerEditor.applyEditorValue(ColumnViewerEditor.java:299) at org.eclipse.jface.viewers.ColumnViewerEditor.handleEditorActivationEvent(ColumnViewerEditor.java:416) at org.eclipse.jface.viewers.ColumnViewer.triggerEditorActivationEvent(ColumnViewer.java:677) at org.eclipse.jface.viewers.ColumnViewer.handleMouseDown(ColumnViewer.java:652) at org.eclipse.jface.viewers.ColumnViewer.access$0(ColumnViewer.java:648) at org.eclipse.jface.viewers.ColumnViewer$1.mouseDown(ColumnViewer.java:97) at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:193) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817) at org.eclipse.jface.window.Window.runEventLoop(Window.java:818) at org.eclipse.jface.window.Window.open(Window.java:794) at com.highgo.admin.migrator.handler.OpenMigratorHandler.execute(OpenMigratorHandler.java:28) at com.highgo.admin.NavigatorActionExecuteAdvanceTool.executeTool(NavigatorActionExecuteAdvanceTool.java:46) at com.highgo.admin.NavigatorActionExecuteAdvanceTool.run(NavigatorActionExecuteAdvanceTool.java:37) at org.jkiss.dbeaver.ui.ActionUtils$1.run(ActionUtils.java:267) at org.eclipse.jface.action.Action.runWithEvent(Action.java:473) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:565) at org.eclipse.jface.action.ActionContributionItem.lambda$4(ActionContributionItem.java:397) at org.eclipse.jface.action.ActionContributionItem$$Lambda$148/1073564434.handleEvent(Unknown Source) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:86) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4428) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4238) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3817) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1044) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:680) at org.eclipse.ui.internal.Workbench$$Lambda$14/1717433286.run(Unknown Source) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148) at org.jkiss.dbeaver.core.application.DBeaverApplication.start(DBeaverApplication.java:160) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) at org.eclipse.equinox.launcher.Main.run(Main.java:1499) at org.eclipse.equinox.launcher.Main.main(Main.java:1472)

2
Gets an ArrayOutOfBoundException where? Show us the stack trace.greg-449
I updated my code and the stack trace.khunnie
What line is line 77? You are indexing array outside its bounds on that line. Do some debugging to work out why.greg-449
I think the reason is that I used a ComboBoxCellEditor, and when I edit the cell, the Object userInputValue will be casted to Integer type, which will be the comboIndex. So the comboIndex is out of array bound. I want to edit the cell if I choose " " item in the combobox. Is that possible?khunnie
For a editable ComboBoxCellEditor, we can use a new ComboBoxCellEditor which extends the old one, and override its doSetValue() method and doGetValue() method. That can make the ComboBoxCellEditor editable.khunnie

2 Answers

1
votes

A ComboBoxCellEditor is editable per se, as it uses a JFace Combo (excactly a CCombo). One can easily overwrite the selected text. In this case setValue returns -1 as value (in OP's code userInputValue).

So to get an editable ComboBoxCellEditor is is sufficient to handle this value in the setValue-method:

@Override
protected void setValue(Object element, Object value) {
    if ((int)value == -1) {
        str[1] = ((CCombo)editor.getControl()).getText();
    } else {
        str[1] = names[(int)value];
    }
    viewer.update(element, null);
}
0
votes

For a editable ComboBoxCellEditor, we can use a new ComboBoxCellEditor which extends the old one, and override its doSetValue() method and doGetValue() method. That can make the ComboBoxCellEditor editable.

protected void doSetValue(final Object value) {
    if (value instanceof String) {
        ((CCombo) getControl()).setText((String) value);
    } else {
        super.doSetValue(value);
    }
}

@Override
protected Object doGetValue() {
    final Object value = super.doGetValue();
    if (value instanceof Integer && (Integer) value == -1) {
        return ((CCombo) getControl()).getText();
    }
    return value;
}