2013-01-17 2 views
3

구현 된 CheckboxTreeViewer은 Linux 데비안에서 완벽하게 작동하지만 Windows에서는 그렇지 않습니다. 무엇보다도 먼저 "setGrayed()"개념을 이해하지 못합니다. 엘리먼트의 하위 부분 만 선택된다는 것을 보여 주나요?CheckboxTreeViewer를 올바르게 사용하는 방법은 무엇입니까?

그래서 문제 : Windows에서 항목을 검사하면 트리의 다른 모든 요소를 ​​검사합니다. 어떻게 든 전체 논리는 무시됩니다.

@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); 
     } 

    } 
} 

편집 :

여기 ICheckStateListener에서 내 코드 내가

감사합니다 사전에 이클립스 인디고

를 사용하고 있습니다!

답변

6

트리의 확인란이 회색으로 표시된 상태는 선택되거나 선택 취소 된 상태뿐입니다. 당신의 사용 방법은 당신에게 달려 있지만, 일반적으로 "부분 체크"상태를 의미합니다. 일반적으로 항목에 체크 된 자식이 있고 체크되지 않은 항목이있는 경우 부모는 선택된 + 회색 상태를 표시합니다. 이것이 정확히 어떻게 렌더링되는지는 OS와 버전에 따라 다릅니다. 일부 구현에서 사용자는 트리 항목 만 선택 또는 선택 취소 할 수 있으며 마우스 클릭을 통해 항목에 회색 상태를 명시 적으로 설정할 수 없습니다. 확인 된 하위 항목에 따라 자동으로 발생합니다. 그러나 때로는 확인란을 클릭하여 회색으로 표시하여 선택하지 않도록 설정할 수있는 응용 프로그램도 있습니다. 이 경우 회색 상태는 종종 "기본"상태를 의미합니다. 어쨌든 이것은 구현에 달려 있습니다.

나는 당신이 직면하고있는 문제가 정확히 무엇인지 확신 할 수 없지만, 추측해야만한다면 위젯은 이벤트를 던질 때 데비안 대 Windows에서 다르게 행동한다고 ​​말할 것입니다. 구현시 항목이 검사 될 때마다 모든 부모와 모든 자식을 검사하므로 Windows의 부모에 대해 을 호출하면 이벤트가 시작되고 부모의 모든 자식을 검사하는 수신기가 호출 될 수 있습니다 따라서 모든 것이 가능해진다. 그것을 테스트하고 이것이 문제인지 확인하십시오. 이를 피하려면 이벤트를 처음 수정할 때 설정 한 플래그를 작성한 다음 수정하십시오. 그리고 수정하는 동안 요소에 대한 변경 사항이 전체 트리에 반복적으로 적용되지 않도록 해당 플래그가 설정된 경우 모든 checkStateChanged() 이벤트 호출을 무시합니다. 한 항목에 대한 작업이 완료되면 체크/체크되지 않은 작업으로 플래그를 재설정하여 사용자 이벤트를 다시 처리 할 수 ​​있습니다.

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; 
    } 
} 
관련 문제