Step 1 - Identify the Parent Child Relationship and Objects required for that. Lets take an example of Directory and File Listing. So in that Case our Directory class is the parentClass and File is the childClass.
Step 2 - Identify the way by which child objects would be retrieved using parent objects. For example there could be a method in Directory class for getting files. Lets say - getFiles().
Step 3 - Identofy the way to find the parent using the child object. Lets say method in File Class - getDirectory().
Step 4 - Create a Tree Content Provider Class. This class will establish the relationship between parent and child object.
Tree Content Provider
public class MyTreeContentProvider implements ITreeContentProvider
{
@Override
public Object[] getChildren(Object parentElement)
{
if (parentElement instanceof Directory)
{
return ((Directory) parentElement).getFiles().toArray();
} else if((parentElement instanceof List)) {
return ((List) parentElement).toArray();
}
else
{
return null;
}
}
@Override
public Object getParent(Object element)
{
if (element instanceof childClass)
{
return ((parentClass) element.getParent()).
}
return null;
}
@Override
public boolean hasChildren(Object element)
{
Object[] obj = getChildren(element);
if (obj == null)
{
return false;
}
return (obj.length > 0);
}
@Override
public Object[] getElements(Object inputElement)
{
if (inputElement instanceof List)
{
return ((List) inputElement).toArray();
}
else if (inputElement instanceof parentClass)
{
return ((parentClass) inputElement).getChildElements().toArray();
}
return null;
}
@Override
public void dispose()
{
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
}
}
Step 5 - Create a Tree Label Provider Class. This class will help identify the images and texts to be placed in table tree cells.
Tree Label Provider Class
public class MyTreeLabelProvider extends LabelProvider implements ITableLabelProvider
{
@Override
public Image getColumnImage(Object element, int columnIndex)
{
return null;
}
@Override
public String getColumnText(Object element, int columnIndex)
{
if (element instanceof ParentClass)
{
ParentClass parentObj = (ParentClass)element;
switch (columnIndex)
{
case 0:
displayText = parentObj.getColumn1Value();
break;
case 1:
displayText = parentObj.getColumn2Value();
break;
case 2:
displayText = parentObj.getColumn3Value();
break;
}
} else if (element instanceof ChildClass) {
ChildClass childObj = (ChildClass)element;
switch (columnIndex)
{
case 0:
displayText = childObj.getColumn1Value();
break;
case 1:
displayText = childObj.getColumn2Value();
break;
case 2:
displayText = childObj.getColumn3Value();
break;
}
}
return displayText;
}
}
Step 6 - Create Listener Classes for actions to be taken on events.
Listener Class for Delete Key event
class TestListener implements KeyListener
{
@Override
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.DEL) {
// Provide the implementation here.
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Step 7 - Create the Tree Component
a. Create a composite.
b. new Tree
c. Set Column Header Text and Column Layout.
d. Set the Grid Layout
e. Create a Tree Viewer out of the created Tree
f. Set Content Provider Class for the Tree Viewer
g. Set Label Provider Class for the Tree Viewer
h. Set other Properties
i. Add Listeners to the tree
Code to create Tree
treeViewerComposite = new Composite(this, SWT.NONE);
Tree tree = new Tree(treeViewerComposite, SWT.BORDER | SWT.MULTI);
tree.setHeaderVisible(true);
TreeColumnLayout columnLayout = new TreeColumnLayout();
treeViewerComposite.setLayout(columnLayout);
TreeColumn column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN1_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(3,0));
column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN2_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(3,0));
column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN7_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(3,0));
GridDataFactory.fillDefaults().grab(true, true).hint(VIEWER_WIDTH, VIEWER_HEIGHT).applyTo(treeViewerComposite);
TreeViewer treeViewer = new TreeViewer(tree);
treeViewer .setContentProvider(new MyTreeContentProvider ());
treeViewer .setLabelProvider(MyTreeLabelProvider );
treeViewer .getTable().setHeaderVisible(true);
tree.addKeyListener(new TestListener());
Additional Code Snippets
Code Snippet for implementing a Delete Key Listener to Delete a tree row.
class DeleteModifierKeyListener implements KeyListener
{
@Override
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.DEL) {
IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
if (selection.isEmpty()) {
return;
} else {
TreeItem[] items = treeViewer.getTree().getSelection();
for (TreeItem treeItem : items)
{
list.remove(treeItem.getData());
}
treeViewer.refresh();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Adding a Context Menu to Tree Viewer
Menu menu1 = new Menu(treeViewer.getTree());
MenuItem item = new MenuItem(menu1, SWT.PUSH);
item.setText("Test 1");
item.addSelectionListener(new Test1Listener());
MenuItem item = new MenuItem(menu1, SWT.PUSH);
item1.setText("Test2");
item1.addSelectionListener(new Test2Listener());
treeViewer.getTree().setMenu(menu1);
MenuItem item = new MenuItem(menu1, SWT.PUSH);
item.setText("Test 1");
item.addSelectionListener(new Test1Listener());
MenuItem item = new MenuItem(menu1, SWT.PUSH);
item1.setText("Test2");
item1.addSelectionListener(new Test2Listener());
treeViewer.getTree().setMenu(menu1);
Different Context Menus for Parent and Child Rows
@Override
public void menuDetected(MenuDetectEvent e) {
// get the selected items
ISelection selection = (IStructuredSelection) treeViewer.getSelection();
// define menus - menu 1 if right click on parent tree item
Menu menu1 = new Menu(treeViewer.getTree());
MenuItem item = new MenuItem(menu1, SWT.PUSH);
item.setText("Test 1");
item.addSelectionListener(new Test1Listener());
// menu 2 if right click on child tree item
Menu menu2 = new Menu(TreeViewer.getTree());
MenuItem item1 = new MenuItem(menu2, SWT.PUSH);
item1.setText("Test2");
item1.addSelectionListener(new Test2Listener());
// menu 3 if right click on neither the parent tree item or child tree item. ex - menu for headers.
Menu menu3 = new Menu(TreeViewer.getTree());
MenuItem item1 = new MenuItem(menu3, SWT.PUSH);
item1.setText("Test3");
item1.addSelectionListener(new Test3Listener());
// check if the tree item selected is parent or child and set the menu accordingly
if (selection.getFirstElement() instanceof <ParentClass> ) {
treeViewer.getControl().setMenu(menu1);
} else if (selection.getFirstElement() instanceof <ChildClass> )
treeViewer.getControl().setMenu(menu2);
} else {
treeViewer.getControl().setMenu(menu3);
}
// clear the selection
treeViewer.setSelection(null);
}
});
Changing the width of the Columns
treeViewer.setLayout(columnLayout);
TreeColumn column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN1_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(2,0));
column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN2_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(1,0));
column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN7_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(5,0));
So out of the three columns , the first column will take up 2/(2+1+5) = 1/4 of the width , second column will take 1/8 , and third will take rest 5/8.
Specifying the minimum width for the columns
treeViewer.setLayout(columnLayout);
TreeColumn column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN1_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(2,3));
column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN2_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(1,1));
column = new TreeColumn(tree, SWT.NONE);
column.setText(COLUMN3_NAME);
columnLayout.setColumnData(column, new ColumnWeightData(5,10));
Expand the tree by default
treeViewer.expandAll();
Setting / unsetting the tree row selection
treeViewer.setSelection(null);
ISelection selection = (IStructuredSelection) treeViewer.getSelection();
treeViewer.setSelection(selection