Saturday 21 January 2017

jFace: TreeViewer example

By using TreeViewer, we can display tree kind of structures. You need to provide the content and label provider to a TreeViewer.

Following step-by-step procedure explains how to develop simple TreeViewer application. After this, I will show you complete application, where you can build a file viewer in tree format.

First step is, you need to provide content to a treeviewer by implementing ITreeContentProvider interface
ITreeContentProvider provide content to tree-structure-oriented viewers. Your custom content provider must provide implementation for following methods declared in ITreeContentProvider interface.

Method
Description
Object[] getElements(Object inputElement)
Returns the elements to display in the viewer when its input is set to the given element, getElements is called to obtain the tree viewer's root elements
Object[] getChildren(Object parentElement)
Returns the child elements of the given parent element.
Object getParent(Object element)
Returns the parent for the given element, or null indicating that the parent can't be computed.
boolean hasChildren(Object element)
Return true if the given element has children, and false if it has no children

For example, I implemented CustomTreeContentProvider class like below.
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import java.util.*;

public class CustomTreeContentProvider implements ITreeContentProvider {
 private Map<String, String[]> contentMap = new HashMap<>();

 public CustomTreeContentProvider() {
  initMap();
 }

 private void initMap() {
  String[] roots = { "root1", "root2" };

  contentMap.put("roots", roots);

  contentMap.put("root1", new String[] { "root1_child1", "root1_child2", "root1_child3" });
  contentMap.put("root1_child1", new String[] { "root1_child1_child1", "root1_child1_child2" });
 }

 @Override
 public Object[] getElements(Object arg0) {
  return contentMap.get("roots");
 }

 @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) {
  return contentMap.get(arg0);
 }

 @Override
 public Object getParent(Object arg0) {
  return getParentOfEle(arg0);
 }

 @Override
 public boolean hasChildren(Object arg0) {
  return contentMap.containsKey(arg0);
 }

 private String getParentOfEle(Object arg0) {
  Set<String> keys = contentMap.keySet();

  for (String key : keys) {
   String[] values = contentMap.get(key);

   for (String val : values) {
    if (val.equals(arg0)) {
     return key;
    }
   }
  }
  return null;
 }

}

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class TreeViewerDemo extends ApplicationWindow {

 public TreeViewerDemo() {
  super(null);

 }
 
 /**
  * Runs the application
  */
 public void run() {
  // Don't return from open() until window closes
  setBlockOnOpen(true);

  // Open the main window
  open();

  // Dispose the display
  Display.getCurrent().dispose();
 }

 protected void configureShell(Shell shell) {
  super.configureShell(shell);

  // Set the title bar text and the size
  shell.setText("File Tree");
  shell.setSize(400, 400);
 }

 protected Control createContents(Composite parent) {
  Composite composite = new Composite(parent, SWT.NONE);
  composite.setLayout(new GridLayout(1, false));

  final TreeViewer tv = new TreeViewer(composite);
  tv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
  tv.setContentProvider(new CustomTreeContentProvider());

  tv.setInput("root");

  return composite;
 }

}

public class TreeViewerDemoTest {
 public static void main(String args[]){
  TreeViewerDemo treeViewer = new TreeViewerDemo();
  treeViewer.run();
 }
}
Run above application, you can able to see following window.
Adding labels (or) images to TreeViewer
By implementing the interface ‘ILabelProvider’, you can add labels (or) images to TreeViewer contents.

ILabelProvider interface provides following methods to implement.

Method
Description
Image getImage(Object element)
Returns the image for the label of the given element.
String getText(Object element)
Returns the text for the label of the given element.
void addListener(ILabelProviderListener listener)
Adds a listener to this label provider. Has no effect if an identical listener is already registered.
void dispose()
Disposes of this label provider. You can close the resources here.
boolean isLabelProperty(Object element,String property)
Returns whether the label would be affected by a change to the given property of the given element.
void removeListener(ILabelProviderListener listener)
Removes a listener to this label provider. Has no effect if an identical listener is not registered.

Following is my CustomTreeLabelProvider implementation.
Make sure you updated the property ‘imageLocation’ to some valid file path.
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;

public class CustomTreeLabelProvider implements ILabelProvider {

 private Image dir;
 private static String imageLocation = "C:\\Users \\Downloads\\icons\\folder.jpg";

 public CustomTreeLabelProvider() {
  // Create the images
  try {
   dir = new Image(null, new FileInputStream(imageLocation));
  } catch (FileNotFoundException e) {
   // Swallow it; we'll do without images
  }
 }

 @Override
 public void addListener(ILabelProviderListener arg0) {
  // TODO Auto-generated method stub

 }

 @Override
 public void dispose() {
  if (dir != null)
   dir.dispose();
 }

 @Override
 public boolean isLabelProperty(Object arg0, String arg1) {
  // TODO Auto-generated method stub
  return false;
 }

 @Override
 public void removeListener(ILabelProviderListener arg0) {
  // TODO Auto-generated method stub

 }

 @Override
 public Image getImage(Object arg0) {
  return dir;
 }

 @Override
 public String getText(Object arg0) {
  return arg0.toString();
 }

}

Add CustomTreeLabelProvider instance to tree viewer by calling setLabelProvider method.

tv.setLabelProvider(new CustomTreeLabelProvider());


Following is the updated TreeViewerDemo file.
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class TreeViewerDemo extends ApplicationWindow {

 public TreeViewerDemo() {
  super(null);

 }

 /**
  * Runs the application
  */
 public void run() {
  // Don't return from open() until window closes
  setBlockOnOpen(true);

  // Open the main window
  open();

  // Dispose the display
  Display.getCurrent().dispose();
 }

 protected void configureShell(Shell shell) {
  super.configureShell(shell);

  // Set the title bar text and the size
  shell.setText("File Tree");
  shell.setSize(400, 400);
 }

 protected Control createContents(Composite parent) {
  Composite composite = new Composite(parent, SWT.NONE);
  composite.setLayout(new GridLayout(1, false));

  final TreeViewer tv = new TreeViewer(composite);
  tv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
  tv.setContentProvider(new CustomTreeContentProvider());
  tv.setLabelProvider(new CustomTreeLabelProvider());

  tv.setInput("root");

  return composite;
 }

}

Re run the class TreeViewerDemoTest, you can able to see following window.

In the coming post, I am going to give complete application that display your system directories in tree view.





Previous                                                 Next                                                 Home

1 comment:

  1. You have the best demo/example for introduction to TreeViewer! Thank you!

    ReplyDelete