如何在 SWT TableViewer 中使用 Enter 键向下导航

发布于 2024-12-05 05:20:00 字数 1316 浏览 1 评论 0原文

我有一个 TableViewer,并且希望在按下 Enter 键时选择向下一个单元格,就像在 MS Excel 中一样。我使用以下 findSelectedCell 实现了自己的 CellNavigationStrategy

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.LEFTViewerCell.RIGHT,这种方法就可以很好地工作。 当我尝试 ViewerCell.ABOVEViewerCell.BELOW nextCell 实际上设置为 上方或下方的单元格,但在 GUI 中,选择保留在 currentSelectedCell 处。

findSelectedCell 的 API 文档说:

退货:

下一个突出显示的单元格,如果默认则为 null 已采取实施。例如,它几乎不可能做出反应 PAGE_DOWN 请求

我不明白那句话是什么意思。谁能向我解释为什么无法将选择设置为下方或上方的单元格?

I have a TableViewer and want the selection to go down one cell when I press the enter key, much like in MS Excel. I implemented my own CellNavigationStrategy with the following 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;
                    }

This works pretty well as long as I have ViewerCell.LEFT or ViewerCell.RIGHT.
When I try ViewerCell.ABOVE or ViewerCell.BELOW nextCell is actually set to the
cell above or below, but in the GUI the selection stays at currentSelectedCell.

The API-Documentation for findSelectedCell says:

Returns:

the cell which is highlighted next or null if the default
implementation is taken. E.g. it's fairly impossible to react on
PAGE_DOWN requests

I do not understand what that sentence means. Can anyone exlain to me why it is not possible to set the selection to a cell below or above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泛滥成性 2024-12-12 05:20:00

当我尝试 ViewerCell.ABOVE 或 ViewerCell.BELOW 时,nextCell 实际上是
设置为上方或下方的单元格,但在 GUI 中,选择保持在
当前选定的单元格。

您必须在 KEY_PRESSED 事件之后显式设置当前选择。现在有两种方法可以做到这一点。

  1. v.getTable().showColumn(v.getTable().getColumn(nextCell.getColumnIndex())); 其中是表查看器 对象。现在,这种方法通常适用于简单的按键,如 SWT.ARROW_DOWNSWT.ARROW_UP 等。但是回车符,即 SWT.CR 通常有一些特殊含义,例如提交表单、按组合上的默认按钮等。我没有彻底检查,但我的直觉说它是由其他处理程序处理的,因此你会失去焦点。
  2. 对于 SWT.CR 使用: v.getTable().setSelection(((TableItem)nextCell.getItem()));

另外,您还必须覆盖 CellNavigationStrategy.isNavigationEvent(),否则 SWT.CRSWT.KEYPAD_CR 将被忽略。例如:

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


我不明白这句话的意思。

这意味着,如果您要使用 JFace 附带的 CellNavigationStrategy 的默认实现,则无法处理 SWT.PAGE_DOWN 按键事件。原因是它没有在 CellNavigationStrategy.isNavigationEvent() 中处理(有关更多详细信息,请参阅其实现)。


See the full working code below:

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",
                "[email protected]", "M");
        elements[1] = new Person("Boris", "Bokowski",
                "[email protected]","M");
        elements[2] = new Person("Tod", "Creasey", "[email protected]","M");
        elements[3] = new Person("Wayne", "Beaton", "[email protected]","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;
    }

}

When I try ViewerCell.ABOVE or ViewerCell.BELOW nextCell is actually
set to the cell above or below, but in the GUI the selection stays at
currentSelectedCell.

You have to explicitly set the current selection after the KEY_PRESSED event. Now there are two ways to do it.

  1. v.getTable().showColumn(v.getTable().getColumn(nextCell.getColumnIndex())); where is the table viewer object. Now this approach normally works with the simple keys like SWT.ARROW_DOWN, SWT.ARROW_UP etc. But carriage return i.e. SWT.CR usually has some special meaning like submitting a form, pressing a default button on the composite etc. I haven't checked thoroughly but my gut feeling says it is handled by some other handler and hence you lose focus.
  2. For SWT.CR use this: v.getTable().setSelection(((TableItem)nextCell.getItem()));

Also you have to override the CellNavigationStrategy.isNavigationEvent(), otherwise SWT.CR and SWT.KEYPAD_CR would be ignored. For example:

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

I do not understand what that sentence means.

It means that if you are going to use the default implementation of CellNavigationStrategy, which is shipped with JFace then it is not possible to handle the SWT.PAGE_DOWN key press event. The reason is that it is not handled in CellNavigationStrategy.isNavigationEvent() (see its implementation for more details).


See the full working code below:

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",
                "[email protected]", "M");
        elements[1] = new Person("Boris", "Bokowski",
                "[email protected]","M");
        elements[2] = new Person("Tod", "Creasey", "[email protected]","M");
        elements[3] = new Person("Wayne", "Beaton", "[email protected]","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;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文