5

私は問題に直面しています。実装されCheckboxTreeViewerたものは Linux Debian では完璧に動作しますが、Windows では動作しません。まず、「setGrayed()」の概念がわかりません。要素の子の一部のみが選択されていることを示すためですか?

問題: Windows でアイテムをチェックすると、ツリー内の他のすべての要素がチェックされます。どういうわけか、ロジック全体が無視されます。

からの私のコードは次のICheckStateListenerとおりです。

@Override
public void checkStateChanged(final CheckStateChangedEvent event) {
    // object checked
    final TreePath path = ((ITreeSelection) this.treeViewer.getSelection()).getPaths()[0];
    checkChildren(path, event.getChecked());
    checkParents(path.getParentPath());
    syncData();
}

public void checkParents(final TreePath path) {
    if (path == null) {
        return;
    }
    final IFieldElement<Object> treeElement = (IFieldElement<Object>) path.getLastSegment();
    if (treeElement != null) {
        boolean allChecked = true;
        boolean allUnchecked = true;
        for (final Object fieldElement : treeElement.getChildrenElements()) {
            allChecked = allChecked && this.treeViewer.getChecked(fieldElement);
            allUnchecked = allUnchecked && !this.treeViewer.getChecked(fieldElement);
        }
        if (allUnchecked) {
            this.treeViewer.setChecked(treeElement, false);
            this.treeViewer.setGrayed(treeElement, false);
        } else
        if (allChecked) {
            this.treeViewer.setChecked(treeElement, true);
            this.treeViewer.setGrayed(treeElement, false);
        } else
        if (!allUnchecked && !allChecked) {
            this.treeViewer.setChecked(treeElement, true);
            this.treeViewer.setGrayed(treeElement, true);
        }
    }
    checkParents(path.getParentPath());
}

public void checkChildren(final TreePath path, final boolean checked) {
    if (path == null) {
        return;
    }
    final Object element = path.getLastSegment();
    if (element != null) {
        this.treeViewer.setChecked(element, checked);
        this.treeViewer.setGrayed(element, false);
        this.treeViewer.setSubtreeChecked(element, checked);
        if (element instanceof EventMethod) {
            checkEventMethod(path, element, checked);
        }

    }
}

編集:Eclipse Indigoを使用しています

前もって感謝します!

4

2 に答える 2

7

ツリー内のチェックボックスの「灰色」の状態は、オンとオフに加えて、単なる別の状態です。使い方は自由ですが、一般的には「部分チェック」状態を意味します。一般的に、アイテムにチェックされた子とチェックされていない子が含まれている場合、親はチェックされた+灰色の状態を示します。これがどの程度正確にレンダリングされるかは、OS とそのバージョンによって異なります。一部の実装では、ユーザーはツリー アイテムをオンまたはオフにすることしかできず、マウス クリックによってアイテムを明示的にグレー状態に設定することはできません。チェックされた子に応じて自動的に発生します。ただし、チェックボックスをクリックして、チェックをオンにしたり、グレー表示にしたり、オフにしたりできるアプリケーションもあります。このような場合の灰色の状態は、多くの場合、「デフォルト」状態を意味します。とにかく、これは実装に依存します。

あなたが直面している問題が何であるかは正確にはわかりませんが、推測する必要がある場合は、イベントのスローに関して、Debian と Windows でウィジェットの動作が異なると言えます。実装では、アイテムがチェックされるたびに、そのすべての親とそのすべての子をチェックするためtreeViewer.setChecked()、Windows で親を呼び出すとイベントのスローも開始され、リスナーが呼び出されてすべての親のすべての子がチェックされる可能性があります。すべてが有効になります。テストして、これが問題かどうかを確認してください。これを回避するには、何かを変更する前に最初にイベントを受け取ったときに設定するフラグを作成します。そして、変更中はすべて無視しますcheckStateChanged()要素への変更がツリー全体に再帰的に適用されないように、そのフラグが設定されている限り、イベント呼び出し。1 つの項目のチェック済み/未チェック アクションの操作が完了したら、フラグをリセットして、ユーザー イベントを再び処理できるようにします。

private boolean ignoreCheckEvent = false;

@Override
public void checkStateChanged(final CheckStateChangedEvent event) {
    if (ignoreCheckEvent)
        return;

    ignoreCheckEvent = true;

    try {
        // object checked
        final TreePath path = ((ITreeSelection) this.treeViewer.getSelection()).getPaths()[0];
        checkChildren(path, event.getChecked());
        checkParents(path.getParentPath());
        syncData();
    }
    finally {
        ignoreCheckEvent = false;
    }
}
于 2013-01-18T15:50:39.587 に答える