Как перейти вниз с помощью клавиши ввода в SWT TableViewer - PullRequest
2 голосов
/ 16 сентября 2011

У меня есть TableViewer, и я хочу, чтобы выделение уменьшалось на одну ячейку при нажатии клавиши ввода, как в MS Excel.Я реализовал свой собственный CellNavigationStrategy со следующим findSelectedCell.

public ViewerCell findSelectedCell(ColumnViewer viewer,
                            ViewerCell currentSelectedCell, Event event) {
                        if (event.type == ColumnViewerEditorActivationEvent.KEY_PRESSED) {
                            if (event.keyCode == SWT.CR
                                    || event.keyCode == SWT.KEYPAD_CR) {
                                ViewerCell nextCell = currentSelectedCell
                                        .getNeighbor(ViewerCell.BELOW, false);
                                return nextCell;
                            }
                        }
                        return null;
                    }

Это работает довольно хорошо, пока у меня есть ViewerCell.LEFT или ViewerCell.RIGHT.Когда я пытаюсь ViewerCell.ABOVE или ViewerCell.BELOW nextCell фактически устанавливается в ячейку выше или ниже, но в GUI выбор остается на currentSelectedCell.

Документация API для findSelectedCell говорит:1015 *

Возвращает:

ячейку, которая выделяется следующей или нулевой, если используется реализация по умолчанию.Например, на запросы PAGE_DOWN довольно невозможно реагировать

Я не понимаю, что означает это предложение.Может кто-нибудь объяснить мне, почему невозможно установить выделение для ячейки ниже или выше?

1 Ответ

3 голосов
/ 29 сентября 2011

Когда я пытаюсь использовать ViewerCell.ABOVE или ViewerCell.BELOW, nextCell фактически устанавливается на ячейку выше или ниже, но в графическом интерфейсе выбор остается на currentSelectedCell.

Вы должны явноустановить текущий выбор после события KEY_PRESSED.Теперь есть два способа сделать это.

  1. v.getTable().showColumn(v.getTable().getColumn(nextCell.getColumnIndex())); где находится объект table viewer.Теперь этот подход обычно работает с простыми клавишами, такими как SWT.ARROW_DOWN, SWT.ARROW_UP и т. Д. Но возврат каретки, т. Е. SWT.CR, обычно имеет какое-то особое значение, например отправка формы, нажатие кнопки по умолчанию на композите и т. Д. Я не проверялполностью, но мое внутреннее чувство говорит, что оно обрабатывается каким-то другим обработчиком, и поэтому вы теряете фокус.
  2. Для SWT.CR используйте это: v.getTable().setSelection(((TableItem)nextCell.getItem()));

Также вы должны переопределитьCellNavigationStrategy.isNavigationEvent(), иначе SWT.CR и SWT.KEYPAD_CR будут игнорироваться. Например:

@Override
public boolean isNavigationEvent(ColumnViewer viewer, Event event) {
    return event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR;
}


Я не понимаючто означает это предложение.

Это означает, что если вы собираетесь использовать реализацию по умолчанию CellNavigationStrategy, поставляемую с JFace, то невозможно обработать событие нажатия клавиши SWT.PAGE_DOWN,Причина в том, что он не обрабатывается в CellNavigationStrategy.isNavigationEvent() (см. Подробности в его реализации).


См. Полный рабочий код ниже:
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;

public class CellNavTest {
    public CellNavTest(Shell shell)
    {
        final TableViewer v = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION);
        v.setContentProvider(new MyContentProvider());

        TableViewerColumn column = new TableViewerColumn(v, SWT.NONE);
        column.getColumn().setWidth(200);
        column.getColumn().setText("Givenname");
        column.getColumn().setMoveable(true);
        column.setLabelProvider(new ColumnLabelProvider() {

            public String getText(Object element) {
                return ((Person) element).givenname;
            }
        });

        column = new TableViewerColumn(v, SWT.NONE);
        column.getColumn().setWidth(200);
        column.getColumn().setText("Surname");
        column.getColumn().setMoveable(true);
        column.setLabelProvider(new ColumnLabelProvider() {

            public String getText(Object element) {
                return ((Person) element).surname;
            }

        });

        column = new TableViewerColumn(v, SWT.NONE);
        column.getColumn().setWidth(200);
        column.getColumn().setText("E-Mail");
        column.getColumn().setMoveable(true);
        column.setLabelProvider(new ColumnLabelProvider() {

            public String getText(Object element) {
                return ((Person) element).email;
            }

        });

        CellNavigationStrategy naviStrat = new CellNavigationStrategy() 
        {

            @Override
            public boolean isNavigationEvent(ColumnViewer viewer, Event event) {
                return event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR;
            }

            public ViewerCell findSelectedCell(ColumnViewer viewer, ViewerCell currentSelectedCell, Event event)
            {
                if (event.type == ColumnViewerEditorActivationEvent.KEY_PRESSED) {
                    if (event.keyCode == SWT.CR  || event.keyCode == SWT.KEYPAD_CR) 
                    {
                        ViewerCell nextCell = currentSelectedCell.getNeighbor(ViewerCell.BELOW, false);
                        if(nextCell != null) 
                        {
                            /*
                             * START
                             * Shows the column. If the column is already showing in the receiver, this method simply returns. 
                             * Otherwise, the columns are scrolled until the column is visible. So when you press enter it will just
                             * return the same column index and hence as per javadoc it will just return.
                             */
                            //System.out.println(nextCell.getColumnIndex());
                            //v.getTable().showColumn(v.getTable().getColumn(nextCell.getColumnIndex()));
                            /*
                             * END
                             */

                            if(nextCell.getItem() instanceof TableItem)
                                v.getTable().setSelection(((TableItem)nextCell.getItem()));
                        }
                        return nextCell;
                    }
                }
                return null;
            }

        };

        new TableViewerFocusCellManager(v, new FocusCellOwnerDrawHighlighter(v), naviStrat);    

        Person[] model = createModel();
        v.setInput(model);
        v.getTable().setLinesVisible(true);
        v.getTable().setHeaderVisible(true);
    }

    private Person[] createModel() {
        Person[] elements = new Person[4];
        elements[0] = new Person("Tom", "Schindl",
                "tom.schindl@bestsolution.at", "M");
        elements[1] = new Person("Boris", "Bokowski",
                "Boris_Bokowski@ca.ibm.com","M");
        elements[2] = new Person("Tod", "Creasey", "Tod_Creasey@ca.ibm.com","M");
        elements[3] = new Person("Wayne", "Beaton", "wayne@eclipse.org","M");

        return elements;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Display display = new Display();

        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        new CellNavTest(shell);
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }

        display.dispose();

    }
}

class MyContentProvider implements IStructuredContentProvider {

    public Object[] getElements(Object inputElement) {
        return (Person[]) inputElement;
    }
    public void dispose() {
    }
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }
}

class Person {
    public String givenname;
    public String surname;
    public String email;
    public String gender;
    public Person(String givenname, String surname, String email, String gender) {
        this.givenname = givenname;
        this.surname = surname;
        this.email = email;
        this.gender = gender;
    }

}
...