checkboxTreeViewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
Object element = event.getElement();
ITreeContentProvider contentProvider = (ITreeContentProvider) checkboxTreeViewer.getContentProvider();
alterChildren(element, contentProvider, event.getChecked());
alterParents(element, contentProvider);
}
private void alterChildren(Object element, ITreeContentProvider contentProvider, boolean checked) {
Queue<Object> toRecurse = new LinkedList<Object>();
toRecurse.offer(element);
while (!toRecurse.isEmpty()) {
Object o = toRecurse.poll();
for (Object child : contentProvider.getChildren(o)) {
if (contentProvider.hasChildren(child))
toRecurse.offer(child);
checkboxTreeViewer.setChecked(child, checked);
checkboxTreeViewer.setGrayed(child, false);
}
}
}
private void alterParents(Object element, ITreeContentProvider contentProvider) {
Object parent = contentProvider.getParent(element);
while (parent != null) {
boolean allChecked = true;
boolean noneChecked = true;
for (Object child : contentProvider.getChildren(parent)) {
boolean checked = checkboxTreeViewer.getChecked(child);
boolean grayed = checkboxTreeViewer.getGrayed(child);
allChecked &= checked & !grayed;
noneChecked &= !checked;
}
if (allChecked) {
checkboxTreeViewer.setChecked(parent, true);
checkboxTreeViewer.setGrayed(parent, false);
} else if (noneChecked) {
checkboxTreeViewer.setGrayChecked(parent, false);
} else {
checkboxTreeViewer.setGrayChecked(parent, true);
}
parent = contentProvider.getParent(parent);
}
}
});
setControl(checkboxTreeViewer.getControl());