1

Eclipse 4.2 RC1 を使用して、e4 RCP アプリケーションを開発しています。

Composite多数の を含むコントロール ( ) がありますTableViewer。ビューアーは垂直に配置されます。テーブルの最後の要素が選択されているときにユーザーが下矢印を押すと、次のテーブル (下) の最初の要素が選択されるようになります。逆に、最初の要素が選択され、上矢印が押された場合、前のテーブル (上記) の最後の要素が選択されるようにします。私の列の設定のため、単一の を使用することは不可能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);
}

私の混乱は、 と の 2 行e.detail = SWT.TRAVERSE_NONE;にありe.doit = true;ます。この 2 つのステートメントを削除すると、うまくいきません。それらとsetFocusステートメントを削除すると、選択は現在のテーブルの最初または最後の要素に設定され、単一のテーブル内で選択がループされます。detaildoitは、これらのステートメントの前では、それぞれ 32 と false です。

4

2 に答える 2

0

あなたの問題はあなたのselect(DecisionTableTable, int, boolean)方法にあると思います。オーバーライドさsetSelection\selectionChangedれたメソッドの効果が正確かどうかはわかりませんが、複雑すぎるようです。次の方法で要件を達成することはできませんでした:

private void select(DecisionTableTable viewer, int index, boolean reveal) {
    int count = viewer.getTable().getItemCount();
    viewer.setSelection(new StructuredSelection(viewer.getElementAt((index + count) % count), reveal);
}

またdoit=false、イベントを現在のテーブルに適用したくないので、テーブルを切り替えるときに設定する必要があると思います。

于 2012-05-25T16:08:35.637 に答える
0

私にとってうまくいったのは、TransverseListenerの代わりにKeyListenerを実装e.doit = false;し、キーリスナーに行を追加することでした。ある種のイベント伝播が別の選択を引き起こしているようで、上記の行はその伝播を停止しました。これは私の最終的なコードです:

private boolean selecting;
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 (DecisionTableTable 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 (DecisionTableTable viewer : Arrays.asList(ftable, ctable, iatable, catable, pstable))
            if (event.getSelectionProvider() != viewer)
                viewer.setSelection(selection);
        synchronized (this) { selecting = false; }
    }
}

public class KeyHandler extends KeyAdapter {
    public DecisionTableTable p, n;

    public KeyHandler(DecisionTableTable previous, DecisionTableTable next) {
        p = previous; n = next;
    }

    @Override public void keyPressed(KeyEvent e) {
        if (e.getSource() instanceof Table) {
            Table t = (Table) e.getSource();
            if (e.keyCode == SWT.ARROW_UP && p != null && t.getSelectionIndex() == 0) {
                p.getTable().setFocus();
                p.setSelection(new StructuredSelection(p.getElementAt(p.getTable().getItemCount() - 1)));
                e.doit = false;
            } else if (e.keyCode == SWT.ARROW_DOWN && n != null && t.getSelectionIndex() == t.getItemCount() - 1) {
                n.getTable().setFocus();
                n.setSelection(new StructuredSelection(n.getElementAt(0)));
                e.doit = false;
            }
        }
    }
}
于 2012-05-29T17:02:26.427 に答える