Thursday, December 3, 2009

Create eclipse RCP application with tree view and write SWTBot test

We are going to develop our RCP application with a tree view and a write test package using SWTBot for this application.

INPUT POSTS(Create simple eclipse RCP)

Requirement:Eclipse 3.5 Galileo,JDK Version >= 1.5
This ation pplication will display a tree view with root element and two subelement of this root element. These subelement will further have child elements.

Steps:
- Follow all steps given in 'Create simple eclipse RCP' post.
- Create following packages
com.sam.rcp.client.example.model
com.sam.rcp.client.example.provider
com.sam.rcp.client.example.view

- Create these class in respective packages

Person.java
package com.sam.rcp.client.example.model;

public class Person {

String name;
Person parent;
Person[] children = new Person[0];

// constructors
public Person(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person getParent() {
return parent;
}

public void setParent(Person parent) {
this.parent = parent;
}

public Person[] getChildren() {
return children;
}

public void setChildren(Person[] children) {
this.children = children;
}

public Person(String name, Person[] children) {
this.name = name;
this.children = children;
for (Person child : children) {
child.setParent(this);
}
}

}


DataProvider.java
package com.sam.rcp.client.example.provider;

import com.sam.rcp.client.example.model.Person;

public class DataProvider {

public static Person[] getInputData() {
return new Person[] { new Person("Root", new Person[] {
new Person("Parent one", new Person[] {
new Person("Child one-one"),
new Person("Child one-two") }),
new Person("Parent two", new Person[] {
new Person("Child two-one"),
new Person("Child two-two") }) }) };
}
}


MyTreeContentProvider.java
package com.sam.rcp.client.example.provider;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;

import com.sam.rcp.client.example.model.Person;

public class MyTreeContentProvider extends ArrayContentProvider implements
ITreeContentProvider {

public Object[] getChildren(Object parent) {
Person person = (Person) parent;

return person.getChildren();
}

public Object getParent(Object element) {
Person person = (Person) element;
return person.getParent();
}

public boolean hasChildren(Object element) {
Person person = (Person) element;
return person.getChildren().length > 0;
}
}


MyTreeLabelProvider.java
package com.sam.rcp.client.example.provider;

import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

import com.sam.rcp.client.example.model.Person;

public class MyTreeLabelProvider extends LabelProvider {
public Image getImage(Object element) {
Person person = (Person) element;
if (person.getChildren() != null && person.getChildren().length > 0) {
return PlatformUI.getWorkbench().getSharedImages().getImage(
ISharedImages.IMG_OBJ_FOLDER);
}
return PlatformUI.getWorkbench().getSharedImages().getImage(
ISharedImages.IMG_OBJ_ELEMENT);
}

public String getText(Object element) {
Person person = (Person) element;
return person.getName();
}
}


TreeView.java
package com.sam.rcp.client.example.view;

import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

import com.sam.rcp.client.example.provider.DataProvider;
import com.sam.rcp.client.example.provider.MyTreeContentProvider;
import com.sam.rcp.client.example.provider.MyTreeLabelProvider;

public class TreeView extends ViewPart {
private TreeViewer viewer;

public void createPartControl(Composite parent) {
viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setContentProvider(new MyTreeContentProvider());
viewer.setLabelProvider(new MyTreeLabelProvider());
viewer.setInput(DataProvider.getInputData());
}

public void setFocus() {
viewer.getControl().setFocus();
}
}


- In plugin.xml add following extentions

plugin.xml




- When you run this example the output will be


Create SWTBot test for above application: This test will launch an eclipse and perform all operations defined in test class. This will fetch all element of tree in a sequence including leaf child. Then these values will be compared agains given values

TreeViewTest.java:
package com.sam.rcp.client.example;

import junit.framework.TestCase;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;

public class TreeViewTest extends TestCase {
public SWTWorkbenchBot bot;

public TreeViewTest() {
bot = new SWTWorkbenchBot();
}

public void testChangeView() throws Exception {
bot.viewByTitle("Welcome").close();
bot.menu("Window").menu("Show View").menu("Other...").click();
SWTBotShell openViewShell = bot.shell("Show View");
openViewShell.activate();
SWTBotTree tree = bot.tree();
for (SWTBotTreeItem item : tree.getAllItems()) {
if ("Tree View Category".equals(item.getText())) {

item.expand();
for (SWTBotTreeItem element : item.getItems()) {
if ("Tree View".equals(element.getText())) {

element.select();
}
}
}
}
bot.button("OK").click();
String[] expectation = { "Root","Parent one", "Child one-one","Child one-two","Parent two","Child two-one","Child two-two"};
int index = 0;
SWTBotTree viewTree = bot.tree();
for (SWTBotTreeItem item : viewTree.getAllItems()) {
assertEquals(expectation[index++], item.getText());
item.expand();
for (SWTBotTreeItem element : item.getItems()) {
assertEquals(expectation[index++], element.getText());
element.expand();
for (SWTBotTreeItem childElement : element.getItems()) {
assertEquals(expectation[index++], childElement.getText());
}
}
}
}
}

- Run test case

Note: All images can be viewed in new tab/window in proper view.

5 comments:

  1. Hello,
    there seems to be something wrong with ur Article. The "Person.java" is incomplete (or broken...)
    Looking forward reading a working example.

    MfG Martin

    ReplyDelete
  2. sorry i forgott to mention, the "TreeView.java" seems to be missing as well :/

    ReplyDelete
  3. I've tried to follow that example disigning my own model. So I can't provide you with "Person.java" fix.
    But here is a hint to View class:

    ...
    import org.eclipse.jface.viewers.TreeViewer;
    ...
    public class View extends ViewPart {
    public static final String ID = "TreeView.view";

    private TreeViewer viewer;

    public void createPartControl(Composite parent) {
    viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
    | SWT.V_SCROLL);
    viewer.setContentProvider(new MyTreeContentProvider());
    viewer.setLabelProvider(new MyTreeLabelProvider());
    // Provide the input to the ContentProvider
    viewer.setInput(DataProvider.getInputData());
    }

    public void setFocus() {
    viewer.getControl().setFocus();
    }
    }

    ReplyDelete
    Replies
    1. That's right the class was broken. I have updated as per your inputs, thanks for the same.

      Delete
  4. Hi
    I have a Shell, In which i have Tree(SWTBotTree) which is In Table Format.
    I want to click on a particular Cell and Enter Text inside the Text Field Enabled after the click.
    After Clicking the Cell and Entering the Text, When i am clicking the Next Cell the Text in the Previous Cell get Disappeared.
    Here is MY code..........

    SWTBotTreeItem[] items = bot.tree().getAllItems();
    for(SWTBotTreeItem ii : items )
    {
    if(ii.select().cell(1).toString().equals("File"))
    {
    ii.select().click(5);
    SWTBotText text = bot.text();
    text.setText("NEw TExt"); // set the text
    }
    if(ii.select().cell(1).toString().equals("MessageType"))
    {
    ii.select().click(5);
    SWTBotText text = bot.text();
    text.setText("NExt TExt"); // set the text

    }
    }

    ReplyDelete