CheckBoxTreeViewer
is used to represent items in the form of tree, and provides checkboxe on each
node. CheckboxTreeViewer provides following constructors to instantiate.
Constructor
|
Description
|
CheckboxTreeViewer(Composite
parent)
|
Creates
a tree viewer on a newly-created tree control under the given parent.
|
CheckboxTreeViewer(Composite
parent, int style)
|
Creates
a tree viewer on a newly-created tree control under the given parent.
|
CheckboxTreeViewer(Tree
tree)
|
Creates
a tree viewer on the given tree control.
|
In this post, I am going to explain how to define checkbox tree viewer by extending the 'CheckboxTreeViewer' class. Since ‘MyCheckBoxTreeViewer’ extends the class CheckboxTreeViewer, you need to use one of the constructors of CheckboxTreeViewer.
We
add some more requirements to ‘MyCheckBoxTreeViewer’.
1. Get notified on any
change in checked state of items
2. Control check,
uncheck and gray check of the checkbox.
Let’s
see the first requirement.
Get notified on any
change in checked state of items
By
implementing the interface 'ICheckStateListener', you will be notified of
changes to the checked state of items in checkbox viewers. This interface
provide 'checkStateChanged' method, it is called when there is a change to the
checked state of an element.
Method
|
Description
|
void
checkStateChanged(CheckStateChangedEvent event)
|
Notifies
of a change to the checked state of an element.
|
Control check,
uncheck and gray check of the checkbox.
By
implementing ICheckStateProvider interface, we can provide checked and grayed
state information about data in trees or tables.
ICheckStateProvider
interface provides following methods to control checked, unchecked and grayed
behavior of tree items.
Method
|
Description
|
boolean
isChecked(Object element)
|
Indicates
if an element's representation should appear as checked or gray instead of
unchecked. If this method returns true the isGrayed(Object) method will
determine whether the check box displays a check mark ("checked")
or a box ("grayed").
|
boolean
isGrayed(Object element)
|
Indicates
whether the check box associated with an element, when checked as indicated
by the isChecked(Object) method, should display the gray (boxed) state
instead of the check mark.
|
Please
read the following points carefully.
If
isChecked is false and isGrayed is false/true then checkbox is unchecked only.
If
isChecked is true and isGrayed is false then checkbox is completely checked.
If
isChecked is true and isGrayed is true then checkbox is gray checked.
To
satisfy requirements 1 & 2 we need to tell MyCheckBoxTreeViewer class about
checkStateProvider and ICheckStateListener implementations.
public void
setCheckStateProvider(ICheckStateProvider checkStateProvider)
Sets
the ICheckStateProvider for this CheckboxTreeViewer. The check state provider
will supply the logic for deciding whether the check box associated with each
item should be checked, grayed or unchecked.
public void
addCheckStateListener(ICheckStateListener listener)
Adds
a listener for changes to the checked state of elements in this viewer. Has no
effect if an identical listener is already registered.
By
setting above two methods to appropriate implementations, we can satisfy the
requirements. Following is the sample structure of MyCheckBoxTreeViewer class.
public class MyCheckBoxTreeViewer extends CheckboxTreeViewer implements ICheckStateListener, ICheckStateProvider { public MyCheckBoxTreeViewer(Composite parent, int style) { super(parent, style); ColumnViewerToolTipSupport.enableFor(this); initializeTree(); } private void initializeTree() { setCheckStateProvider(this); addCheckStateListener(this); } @Override public boolean isChecked(Object arg0) { // TODO Auto-generated method stub return false; } @Override public boolean isGrayed(Object arg0) { // TODO Auto-generated method stub return false; } @Override public void checkStateChanged(CheckStateChangedEvent arg0) { // TODO Auto-generated method stub } }
Now
let’s see how to provide the content to MyCheckBoxTreeViewer.
CheckBoxTreeViewer
class provides 'setContentProvider' method to set the content provider.
public void
setContentProvider(IContentProvider provider)
So
to set the content provider to myCheckBoxTreeViewer class, we need to implement
IContentProvider.
By
implementing 'ITreeContentProvider' interface, you are going to provide
implementation for dispose, inputChanged, getChildren,
getElements,
getParent, hasChildren method.
For
our implementation purpose, I am going to implement getChildren, hasChildren,
getElements methods.
Following
is the dummy implementation of MyCheckBoxTreeContentProvider class.
public class MyCheckBoxTreeContentProvider implements ITreeContentProvider{ @Override public void dispose() { // TODO Auto-generated method stub } @Override public void inputChanged(Viewer arg0, Object arg1, Object arg2) { // TODO Auto-generated method stub } @Override public Object[] getChildren(Object arg0) { // TODO Auto-generated method stub return null; } @Override public Object[] getElements(Object arg0) { // TODO Auto-generated method stub return null; } @Override public Object getParent(Object arg0) { // TODO Auto-generated method stub return null; } @Override public boolean hasChildren(Object arg0) { // TODO Auto-generated method stub return false; } }
Let’s try to provide implementation
for checkStateChanged method
public void
checkStateChanged(CheckStateChangedEvent event)
As
I said previously, this method notifies of a change to the checked state of an
element. By using CheckStateChangedEvent instance, we can get the element whose
check state changed. By using the inbuilt 'findItem' method, we can get the
widget which represents the given element. It returns the corresponding widget,
or null if none.
Now
let’s see how to provide labels to the tree viewer. Since we provide content to
the tree viewer by implementing ‘ITreeContentProvider’, we need to provide a
label for every tree item. We can do this by using ‘setLabelProvider’ method.
Following
is the signature of the ‘setLabelProvider’ method.
public
void setLabelProvider(IBaseLabelProvider labelProvider)
CellLabelProvider
implements IBaseLabelProvider interface.
So by extending CellLabelProvider class, you can provide custom label provider
for 'MyCheckBoxTreeViewer'.
public class MyCheckBoxLabelProvider extends CellLabelProvider { @Override public void update(ViewerCell arg0) { } }
Orders the elements
By
calling the setSorter method on check box tree viewer, you can order the
elements. Following is the signature of the setSorter method.
public
void setSorter(ViewerSorter sorter)
public class MyCheckBoxTreeSorter extends ViewerSorter { @Override public int compare(Viewer viewer, Object left, Object right) { return 0; } }
Following
are the finalized classes.
MyCheckBoxTreeViewer
: extends CheckboxTreeViewer class
MyCheckBoxTreeContentProvider
: Implements ITreeContentProvider interface, and provide content to
MyCheckBoxTreeViewer
MyCheckBoxLabelProvider
: Provide labels to the content of MyCheckBoxTreeViewer
MyCheckBoxTreeSorter
: Order the elements of MyCheckBoxTreeViewer
It
is time to develop an application using these. Following is the requirement.
Build
an application, where all the managers are the childs of your organization
tree. Each manager has 1 (or) more reportees under him.
a. Manager node should
be checked, if all the reportees come to the office today.
b. Manager node should
be gray checked, if some reportees (not all) come to office today
c. Manager node should
be unchecked, if no reportee come today.
d. You can check (or)
uncheck the Manager node.
e. If Manager node is
checked, then all the employee nodes also should be checked.
f. If Manager node is
unchecked, then all the employee nodes should be unchecked.
Let’s
design above application. Following is the complete working example.
Employee.java
package com.sample; public class Employee { private String name; private boolean inOffice; public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isInOffice() { return inOffice; } public void setInOffice(boolean inOffice) { this.inOffice = inOffice; } }
Manager.java
package com.sample; import java.util.ArrayList; import java.util.List; public class Manager { private String name; private final List<Employee> employees = new ArrayList<> (); public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Employee> getEmployees() { return employees; } }
Organization.java
package com.sample; import java.util.ArrayList; import java.util.List; public class Organization { private String name; private List<Manager> managers = new ArrayList<>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public List<Manager> getManagers() { return managers; } }
DataUtil.java
package com.sample; public class DataUtil { public static Organization getOrganization() { Organization oranization = new Organization(); oranization.setName("XYZ Corporation"); Manager manager1 = new Manager(); manager1.setName("Mukund Dixit"); Manager manager2 = new Manager(); manager2.setName("Anand Bandaru"); Manager manager3 = new Manager(); manager3.setName("Shreyas Desai"); Manager manager4 = new Manager(); manager4.setName("VadiRaj"); Employee emp1 = new Employee(); emp1.setInOffice(true); emp1.setName("Keerthi Shetty"); Employee emp2 = new Employee(); emp2.setInOffice(true); emp2.setName("Karthik"); Employee emp3 = new Employee(); emp3.setInOffice(true); emp3.setName("Brijesh"); Employee emp4 = new Employee(); emp4.setInOffice(true); emp4.setName("Deepank Bansal"); Employee emp5 = new Employee(); emp5.setInOffice(true); emp5.setName("Reshmi George"); Employee emp6 = new Employee(); emp6.setInOffice(true); emp6.setName("Janaki Sriram"); Employee emp7 = new Employee(); emp7.setInOffice(false); emp7.setName("Aravind Phaneendra"); Employee emp8 = new Employee(); emp8.setInOffice(true); emp8.setName("Nagendra"); Employee emp9 = new Employee(); emp9.setInOffice(true); emp9.setName("Maruthi"); Employee emp10 = new Employee(); emp10.setInOffice(true); emp10.setName("Piyush"); Employee emp11 = new Employee(); emp11.setInOffice(true); emp11.setName("Shanmugham"); Employee emp12 = new Employee(); emp12.setInOffice(false); emp12.setName("Phalgun Garimella"); Employee emp13 = new Employee(); emp13.setInOffice(false); emp13.setName("Sankalp"); Employee emp14 = new Employee(); emp14.setInOffice(false); emp14.setName("Arpan"); Employee emp15 = new Employee(); emp15.setInOffice(false); emp15.setName("Sandesh"); Employee emp16 = new Employee(); emp16.setInOffice(false); emp16.setName("Senthil"); manager1.getEmployees().add(emp1); manager1.getEmployees().add(emp2); manager1.getEmployees().add(emp3); manager1.getEmployees().add(emp4); manager2.getEmployees().add(emp5); manager2.getEmployees().add(emp6); manager2.getEmployees().add(emp7); manager2.getEmployees().add(emp8); manager3.getEmployees().add(emp9); manager3.getEmployees().add(emp10); manager3.getEmployees().add(emp11); manager4.getEmployees().add(emp12); manager4.getEmployees().add(emp13); manager4.getEmployees().add(emp14); manager4.getEmployees().add(emp15); manager4.getEmployees().add(emp16); oranization.getManagers().add(manager1); oranization.getManagers().add(manager2); oranization.getManagers().add(manager3); oranization.getManagers().add(manager4); return oranization; } }
MyCheckBoxLabelProvider.java
package com.sample; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ViewerCell; public class MyCheckBoxLabelProvider extends CellLabelProvider { @Override public void update(ViewerCell cell) { Object element = cell.getElement(); if (element instanceof Organization) { cell.setText("Org: " + ((Organization) element).getName()); } else if (element instanceof Manager) { cell.setText("M: " + ((Manager) element).getName()); } else { cell.setText("Emp: " + ((Employee) element).getName()); } } }
MyCheckBoxTreeContentProvider.java
package com.sample; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; public class MyCheckBoxTreeContentProvider implements ITreeContentProvider { public MyCheckBoxTreeContentProvider() { } @Override public void dispose() { // TODO Auto-generated method stub } @Override public void inputChanged(Viewer arg0, Object arg1, Object arg2) { // TODO Auto-generated method stub } @Override public Object[] getChildren(Object obj) { if (obj instanceof Organization) { return ((Organization) obj).getManagers().toArray(); } if (obj instanceof Manager) { return ((Manager) obj).getEmployees().toArray(); } return new Object[0]; } @Override public Object[] getElements(Object arg0) { Object[] roots = new Object[1]; roots[0] = DataUtil.getOrganization(); return roots; } @Override public Object getParent(Object arg0) { // TODO Auto-generated method stub return null; } @Override public boolean hasChildren(Object obj) { if (obj instanceof Organization || obj instanceof Manager) { return true; } return false; } }
MyCheckBoxTreeSorter.java
package com.sample; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; public class MyCheckBoxTreeSorter extends ViewerSorter { @Override public int compare(Viewer viewer, Object left, Object right) { if (left instanceof Manager && right instanceof Manager) { return ((Manager) left).getName().compareTo(((Manager) right).getName()); } if (left instanceof Manager && right instanceof Manager) { return ((Employee) left).getName().compareTo(((Employee) right).getName()); } return 0; } }
MyCheckBoxTreeViewer.java
package com.sample; import java.util.List; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ICheckStateProvider; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; public class MyCheckBoxTreeViewer extends CheckboxTreeViewer implements ICheckStateListener, ICheckStateProvider { public MyCheckBoxTreeViewer(Composite parent, int style) { super(parent, style); ColumnViewerToolTipSupport.enableFor(this); initializeTree(); } private void initializeTree() { setCheckStateProvider(this); addCheckStateListener(this); } @Override public boolean isChecked(Object obj) { if (obj instanceof Manager) { Manager manager = (Manager) obj; List<Employee> employees = manager.getEmployees(); for (Employee emp : employees) { if (emp.isInOffice()) { return true; } } } if (obj instanceof Employee) { Employee emp = (Employee) obj; if (emp.isInOffice()) { return true; } } return false; } @Override public boolean isGrayed(Object obj) { int totalEmpsInOffice = 0; if (obj instanceof Manager) { Manager manager = (Manager) obj; List<Employee> employees = manager.getEmployees(); for (Employee emp : employees) { if (emp.isInOffice()) totalEmpsInOffice++; } if (totalEmpsInOffice == employees.size()) { return false; } } if (obj instanceof Employee) { Employee emp = (Employee) obj; return !emp.isInOffice(); } return true; } @Override public void checkStateChanged(CheckStateChangedEvent event) { Object element = event.getElement(); Widget item = findItem(element); if (!(item instanceof TreeItem)) { System.out.println("Given item is not an instance of tree item"); return; } TreeItem treeItem = (TreeItem) item; Object obj = treeItem.getData(); if (obj instanceof Manager) { System.out.println("State is changed for " + ((Manager) obj).getName()); } if (obj instanceof Employee) { System.out.println("State is changed for " + ((Employee) obj).getName()); } } }
TestTreeViewer.java
package com.sample; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class TestTreeViewer { private static int shellWidth = 600; private static int shellHeight = 600; private static int compositeWidth = 500; private static int compositeHeight = 250; private static void addWidgetsToShell(Display display, Shell shell) { Composite composite = new Composite(shell, SWT.BORDER); composite.setBackground(new Color(shell.getDisplay(), 102, 153, 153)); composite.setLayout(new GridLayout()); GridDataFactory.fillDefaults().hint(compositeWidth, compositeHeight).applyTo(composite); MyCheckBoxTreeContentProvider contentProvider = new MyCheckBoxTreeContentProvider(); MyCheckBoxLabelProvider labelProvider = new MyCheckBoxLabelProvider(); MyCheckBoxTreeSorter sorter = new MyCheckBoxTreeSorter(); MyCheckBoxTreeViewer treeViewer = new MyCheckBoxTreeViewer(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); GridDataFactory.fillDefaults().grab(true, true).applyTo(treeViewer.getTree()); treeViewer.setContentProvider(contentProvider); treeViewer.setLabelProvider(labelProvider); treeViewer.setSorter(sorter); treeViewer.setAutoExpandLevel(2); treeViewer.setInput("root"); } public static void main(String[] args) { /* Instantiate Display object, it represents SWT session */ Display display = new Display(); /* * Define Shell, it represent a window, You can add more than one shell * to Display */ Shell shell = new Shell(display); shell.setSize(shellWidth, shellHeight); shell.setLayout(new GridLayout()); addWidgetsToShell(display, shell); /* Open shell window */ shell.open(); /* * Run the event dispatching loop until an exit condition occurs, which * is typically when the main shell window is closed by the user. */ while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } /* Dispose the display */ display.dispose(); } }
TY :D
ReplyDelete