我正在使用 Eclipse 4.2 RC1 开发一个 e4 RCP 应用程序。
我有一个Composite
包含多个TableViewer
s 的控件 ( )。观众是垂直排列的。如果用户在选择表的最后一个元素时点击向下箭头,我希望下一个表(如下)的第一个元素被选中。相反,如果第一个元素被选中并按下向上箭头,我希望上一个表(上图)的最后一个元素被选中。因为我的列设置,不可能使用单个TableViewer
. 在控件的初始化程序中调用以下函数,所有查看器都作为参数传递:
private void init(IEclipseContext context, IMDecisionTable input, DecisionTableTable...viewers) {
for (int i = 0; i < viewers.length; i++) {
viewers[i].hookMenuSupport(context);
viewers[i].setInput(input);
viewers[i].getTable().addTraverseListener(new TraverseSelector(
i > 0 ? viewers[i-1] : null, i < viewers.length - 1 ? viewers[i+1] : null
));
}
}
`TraverseSelector 是我控制的一个嵌套类:
public class TraverseSelector implements TraverseListener {
public DecisionTableTable p, n;
public TraverseSelector(DecisionTableTable previous, DecisionTableTable next) {
p = previous; n = next;
}
@Override public void keyTraversed(TraverseEvent e) {
if (e.getSource() instanceof Table) {
Table t = (Table) e.getSource();
if (e.keyCode == SWT.ARROW_UP && p != null && t.getSelectionIndex() == 0) {
select(p, -1, true);
e.detail = SWT.TRAVERSE_NONE;
e.doit = true;
p.getTable().setFocus();
} else if (e.keyCode == SWT.ARROW_DOWN && n != null && t.getSelectionIndex() == t.getItemCount() - 1) {
select(n, 0, true);
e.detail = SWT.TRAVERSE_NONE;
e.doit = true;
n.getTable().setFocus();
}
}
}
}
当条件满足时,它会尝试适当地设置选择。控件类中的其他相关代码:
private boolean selecting = false;
private ISelection selection = null;
@Override public ISelection getSelection() { return selection; }
@Override public void setSelection(ISelection sel, boolean reveal) {
if (!selecting) {
synchronized (this) { selecting = true; }
selection = sel;
for (TableViewer viewer : Arrays.asList(ftable, ctable, iatable, catable, pstable))
viewer.setSelection(selection, reveal);
synchronized (this) { selecting = false; }
}
}
@Override public void selectionChanged(SelectionChangedEvent event) {
if (!selecting) {
synchronized (this) { selecting = true; }
selection = event.getSelection();
for (ISelectionProvider sp : Arrays.asList(ftable, ctable, iatable, catable, pstable))
if (event.getSelectionProvider() != sp)
sp.setSelection(null);
synchronized (this) { selecting = false; }
}
}
private void select(DecisionTableTable viewer, int index, boolean reveal) {
Table t = viewer.getTable(); int count = t.getItemCount();
setSelection(new StructuredSelection(t.getItem((index + count) % count).getData()), reveal);
}
我的困惑在于这两行e.detail = SWT.TRAVERSE_NONE;
和e.doit = true;
。如果我删除这两个语句,事情就不起作用了。如果我删除这些和setFocus
语句,则选择设置为当前表的第一个或最后一个元素,在单个表中循环选择。detail
在这些陈述之前,doit
分别为 32 和错误。