Using Eclipse TableViewer, how do I navigate and edit cells with arrow keys?
Asked Answered
F

4

13

I am using a TableViewer with a content provider, label provider, a ICellModifier and TextCellEditors for each column.

How can I add arrow key navigation and cell editing when the user selects the cell? I would like this to be as natural a behavior as possible.

After looking at some of the online examples, there seems to be an old way (with a TableCursor) and a new way (TableCursor does not mix with CellEditors??).

Currently, my TableViewer without a cursor will scroll in the first column only. The underlying SWT table is showing cursor as null.

Is there a good example of TableViewer using CellEditors and cell navigation via keyboard?

Thanks!

Formulate answered 2/4, 2009 at 15:51 Comment(0)
N
3

I don't know if there is a good example. I use a cluster of custom code to get what I would consider to be basic table behaviors for my application working on top of TableViewer. (Note that we are still targetting 3.2.2 at this point, so maybe things have gotten better or have otherwise changed.) Some highlights:

  • I do setCellEditors() on my TableViewer.
  • On each CellEditor's control, I establish what I consider to be an appropriate TraverseListener. For example, for text cells:

    cellEditor = new TextCellEditor(table, SWT.SINGLE | getAlignment());
    cellEditor.getControl().addTraverseListener(new TraverseListener() {
        public void keyTraversed(TraverseEvent e) {
            switch (e.detail) {
            case SWT.TRAVERSE_TAB_NEXT:
                // edit next column
                e.doit = true;
                e.detail = SWT.TRAVERSE_NONE;
                break;
    
            case SWT.TRAVERSE_TAB_PREVIOUS:
                // edit previous column
                e.doit = true;
                e.detail = SWT.TRAVERSE_NONE;
                break;
    
            case SWT.TRAVERSE_ARROW_NEXT:
                // Differentiate arrow right from down (they both produce the same traversal @*$&#%^)
                if (e.keyCode == SWT.ARROW_DOWN) {
                    // edit same column next row
                    e.doit = true;
                    e.detail = SWT.TRAVERSE_NONE;
                }
                break;
    
            case SWT.TRAVERSE_ARROW_PREVIOUS:
                // Differentiate arrow left from up (they both produce the same traversal @*$&#%^)
                if (e.keyCode == SWT.ARROW_UP) {
                    // edit same column previous row
                    e.doit = true;
                    e.detail = SWT.TRAVERSE_NONE;
                }
                break;
            }
        }
    });
    

(For drop-down table cells, I catch left and right arrow instead of up and down.)

  • I also add a TraverseListener to the TableViewer's control whose job it is to begin cell editing if someone hits "return" while an entire row is selected.

    // This really just gets the traverse events for the TABLE itself.  If there is an active cell editor, this doesn't see anything.
    tableViewer.getControl().addTraverseListener(new TraverseListener() {
        public void keyTraversed(TraverseEvent e) {
            if (e.detail == SWT.TRAVERSE_RETURN) {
                // edit first column of selected row
            }
        }
    });
    
  • Now, how exactly I control the editing is another story. In my case, my whole TableViewer (and a representation of each column therein) is loosely wrapped up in a custom object with methods to do what the comments above say. The implementations of those methods ultimately end up calling tableViewer.editElement() and then checking tableViewer.isCellEditorActive() to see if the cell was actually editable (so we can skip to the next editable one if not).

  • I also found it useful to be able to programmatically "relinquish editing" (e.g. when tabbing out of the last cell in a row). Unfortunately the only way I could come up with to do that is a terrible hack determined to work with my particular version by spelunking through the source for things that would produce the desired "side effects":

        private void relinquishEditing() {
            // OMG this is the only way I could find to relinquish editing without aborting.
            tableViewer.refresh("some element you don't have", false);
        }
    

Sorry I can't give a more complete chunk of code, but really, I'd have to release a whole mini-project of stuff, and I'm not prepared to do that now. Hopefully this is enough of a "jumpstart" to get you going.

Neaten answered 1/9, 2010 at 13:18 Comment(0)
S
2

Here is what has worked for me:

TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer,new FocusCellOwnerDrawHighlighter(tableViewer));
ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(tableViewer) {
    protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
        return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL 
            || event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION                                   
            || (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR) 
            || event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
       }
};

I can navigate in all directions with tab while editing, and arrow around when not in edit mode.

Subalpine answered 30/11, 2012 at 18:58 Comment(0)
O
0

I got it working based on this JFace Snippet, but I had to copy a couple of related classes also:

  • org.eclipse.jface.snippets.viewers.TableCursor
  • org.eclipse.jface.snippets.viewers.CursorCellHighlighter
  • org.eclipse.jface.snippets.viewers.AbstractCellCursor

and I don't remember exactly where I found them. The is also a org.eclipse.swt.custom.TableCursor, but I couldn't get that to work.

Ourself answered 1/10, 2010 at 16:26 Comment(0)
B
0

Have a look at Example of enabling Editor Activation on a Double Click.

The stuff between lines [ 110 - 128 ] add a ColumnViewerEditorActivationStrategy and TableViewerEditor. In my case the I wanted a single click to begin editing so i changed line 115 from: ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION to ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION. After adding this to my TableViewer, the tab key would go from field to field with the editor enabled.

Bibliolatry answered 24/8, 2011 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.