
Screenshot of application with CheckboxTreeViewer
Today I found out that quite a lot of people struggle with the CheckboxTreeViewer class and especially with the methods:
- setChecked(Object element, boolean state)
- setCheckedElements(Object[] elements)
Those names are very selfexplaining, but still, getting those methods to work took me some time. To shorten up your building time, I will explain how to use the setCheckedElements method in this post. But first I’ll start with the beginning, and that’s the creation of a CheckboxTreeViewer…
So let’s assume you have a Treestructure that you would like to visualize and that structure is build up by two different parts, lets call them Folders and Files. Now, to create the Treestructure we think about a file system, where every Folder can contain zero or multiple Files. You can see a screenshot of the final application on the right, I hope that my structure is a little bit more understandable once you’ve seen the application.
So what do we need to get a CheckboxTreeViewer in our application? Well, you need an CheckboxTreeViewer object and at least one ContentProvider and a LabelProvider.
So lets first start with the ContentProvider
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import be.jcreation.checkboxtreeviewerexample.model.FolderHandler;
import be.jcreation.checkboxtreeviewerexample.model.interfaces.File;
import be.jcreation.checkboxtreeviewerexample.model.interfaces.Folder;
public class TreeContentProvider implements ITreeContentProvider {
@Override
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof Folder){
return ((Folder) parentElement).getAllFiles().toArray();
}
return null;
}
@Override
public Object getParent(Object element) {
if(element instanceof File){
return ((File) element).getFolder();
}
return null;
}
@Override
public boolean hasChildren(Object element) {
if(element instanceof Folder)
return true;
return false;
}
@Override
public Object[] getElements(Object inputElement) {
if(inputElement instanceof Folder){
return ((Folder) inputElement).getAllFiles().toArray();
}
return FolderHandler.getInstance().getAllFolders().toArray();
}
@Override
public void dispose() {}
@Override
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {}
}
The major part of the above code can be found in any book about JFace, but it’s the method getElements(Object inputElement) that has been causing me a lot of problems. As you can see, you also have to keep in mind that the Treestructure should be used here also. So if the inputElement is an object of the class Folder, you should return the children of that object. I assume, I should check the code to be sure of course, that this method is used to search through the structure…
The used LabelProvider isn’t that spectacular, but to give you all the code, here we go:
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import be.jcreation.checkboxtreeviewerexample.model.interfaces.File;
import be.jcreation.checkboxtreeviewerexample.model.interfaces.Folder;
public class LabelProvider implements ILabelProvider {
@Override
public Image getImage(Object element) {
return null;
}
@Override
public String getText(Object element) {
if(element instanceof Folder)
return ((Folder) element).getName();
else if(element instanceof File)
return ((File) element).getName();
return null;
}
@Override
public void addListener(ILabelProviderListener listener) {}
@Override
public void dispose() { }
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {}
}
And last, but not least, how to create the CheckboxTreeViewer, and how to use that setCheckedElements method!
tv = new CheckboxTreeViewer(panel, SWT.NONE);
tv.setContentProvider(new TreeContentProvider());
tv.setLabelProvider(new LabelProvider());
tv.setInput("root");
// When the parent is checked, all children should be checked to
tv.addCheckStateListener(new ICheckStateListener(){
public void checkStateChanged(CheckStateChangedEvent event){
if(event.getChecked()){
tv.setSubtreeChecked(event.getElement(), true);
}
}
});
Button loadSomeSelection = new Button(parent, SWT.PUSH);
loadSomeSelection.setText("Load");
loadSomeSelection.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
tv.setCheckedElements(FolderHandler.getInstance().
getSomeFilesToSelect().toArray());
}
});
If you have read the code carefully, you are now probably wondering what the method getSomeFilesToSelect is returning? Well:
public List<File> getSomeFilesToSelect(){
List<File> selectedFiles = new ArrayList<File>();
for(Folder f : allFolders){
if(f.getAllFiles().size() > 2){
selectedFiles.add(f.getAllFiles().get(2));
}else if(f.getAllFiles().size()>1){
selectedFiles.add(f.getAllFiles().get(1));
}else if(f.getAllFiles().size()>0){
selectedFiles.add(f.getAllFiles().get(0));
}
}
return selectedFiles;
}
This is just some random selection, well not really random but every time the last child of a parent. But to make my point clear, as you can see, I’m giving a list of Files to the setCheckedElements method and those Files are checked (as the screenshot at the top of the page is showing you).
I hope this post is helping those who had the same problem with the CheckboxTreeViewer as I had. And to end my post, I’ll give you the link to my Ecipse Project. It’s an RCP-application to keep it simple.
Jan
Jan SWT - JFace CheckboxTreeViewer, JFace, SWT