How to set double click to edit a Table cell in SWT/JFace?

freitass picture freitass · Dec 21, 2012 · Viewed 7.8k times · Source

Is it possible to change the default behavior of SWT/JFace to enable cell editing only with double clicking? The way it is now (with single click) is hard to select a table row without bringing the text field up.

Here is a self-contained code snippet:

package table.editing;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class TableEditor extends ApplicationWindow {

    class Element {
        private String value;

        public Element(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    public TableEditor() {
        super(null);

        setBlockOnOpen(true);
        open();

        Display.getCurrent().dispose();
    }

    protected Control createContents(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new FillLayout());

        TableViewer viewer = new TableViewer(composite, SWT.MULTI
                | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);

        createColumns(composite, viewer);
        addElements(viewer);

        final Table table = viewer.getTable();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        return composite;
    }

    private void addElements(TableViewer viewer) {
        for (int i = 0; i < 10; i++) {
            viewer.add(new Element("Element " + i));
        }
    }

    private void createColumns(Composite parent, final TableViewer viewer) {
        TableViewerColumn columnViewer = new TableViewerColumn(viewer, SWT.NONE);
        columnViewer.setLabelProvider(new CellLabelProvider() {

            @Override
            public void update(ViewerCell cell) {
                Element element = (Element) cell.getElement();
                cell.setText(element.getValue());
            }
        });
        columnViewer.setEditingSupport(new EditingSupport(viewer) {

            @Override
            protected void setValue(Object element, Object value) {
                ((Element) element).setValue((String) value);
            }

            @Override
            protected Object getValue(Object element) {
                return ((Element) element).getValue();
            }

            @Override
            protected CellEditor getCellEditor(Object element) {
                return new TextCellEditor(viewer.getTable());
            }

            @Override
            protected boolean canEdit(Object element) {
                return true;
            }
        });
        TableColumn column = columnViewer.getColumn();
        column.setText("Example");
        column.pack();
    }

    public static void main(String[] args) {
        new TableEditor();
    }
}

Answer

Waqas Ilyas picture Waqas Ilyas · Dec 21, 2012

You need to set your own TableViewerEditor on the TableViewer. Have a look at the code below:

TableViewer viewer = ...

TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(viewer, new FocusCellOwnerDrawHighlighter(viewer));

ColumnViewerEditorActivationStrategy activationSupport = new ColumnViewerEditorActivationStrategy(viewer) {
    protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
        // Enable editor only with mouse double click
        if (event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION) {
            EventObject source = event.sourceEvent;
            if (source instanceof MouseEvent && ((MouseEvent)source).button == 3)
                return false;

            return true;
        }

        return false;
    }
};

TableViewerEditor.create(viewer, focusCellManager, activationSupport, ColumnViewerEditor.TABBING_HORIZONTAL | 
    ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | 
    ColumnViewerEditor.TABBING_VERTICAL |
    ColumnViewerEditor.KEYBOARD_ACTIVATION);