如何使用SWT TableViewer中的enter键向下导航

我有一个TableViewer ,当我按下回车键时,希望选择按下一个单元格,就像在MS Excel中一样。 我使用以下findSelectedCell实现了我自己的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.LEFTViewerCell.RIGHT这种方法就可以正常工作。 当我尝试ViewerCell.ABOVEViewerCell.BELOW nextCell实际设置为上方或下方的单元格,但在GUI中,选择保持在currentSelectedCell

findSelectedCell的API文档说:

返回:

下一个突出显示的单元格,如果采用默认实现,则为null。 例如,对PAGE_DOWN请求做出反应是不可能的

我不明白那句话是什么意思。 任何人都可以向我说明为什么不能将选择设置为低于或高于某个单元格?

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

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

  1. v.getTable().showColumn(v.getTable().getColumn(nextCell.getColumnIndex())); table viewer对象在哪里。 现在这种方法通常适用于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()处理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; } }