Free tutorials for Java, Eclipse and Web programming



Follow me on twitter

4. Data Binding for JFace Viewer

4.1. Overview

JFace Viewers provide a flexible way of defining the structure and the representation of data separately. The following focuses in using JFace Viewers with JFace Data Binding. For an introduction on JFace Viewers please see JFace Tables and JFace Trees

4.2. JFace Listviewer

In JFace Data Binding for JFace Viewers it is important to distinguish between changes in the collection and changes in the individual object. Our example demonstrates the propagation of changes from the collection to the UI, e.g. if an element will be added or removed to or from the collection this change will be visible in the UI.

JFace Data Binding provides several classes which allow to bind lists to viewers. ObservableListContentProvider is a content provider which requires a list implementing IObservableCollection. We use the class "WritableList" as input for this purpose.

Create a new Eclipse RCP project "de.vogella.databinding.person.listviewer" using the "RCP Application with a view" template. Add again the dependency to your model and the databinding plugins to your plugin project. Change View.java to the following.

				
package de.vogella.databinding.person.listviewer;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

import de.vogella.databinding.person.model.Person;

public class View extends ViewPart {

	private ListViewer viewer;
	private WritableList input;

	@Override
	public void createPartControl(Composite parent) {
		// Just a little bit layout
		parent.setLayout(new GridLayout(3, false));

		// Define the viewer
		viewer = new ListViewer(parent);
		viewer.setContentProvider(new ObservableListContentProvider());
		List<Person> persons = new ArrayList<Person>();
		// Just for testing we create sample data
		createExampleData(persons);
		input = new WritableList(persons, Person.class);
		// Set the writeableList as input for the viewer
		viewer.setInput(input);

		Button delete = new Button(parent, SWT.PUSH);
		delete.setText("Delete");
		delete.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (!viewer.getSelection().isEmpty()) {
					IStructuredSelection selection = (IStructuredSelection) viewer
							.getSelection();
					Person p = (Person) selection.getFirstElement();
					input.remove(p);
				}
			}
		});

		Button add = new Button(parent, SWT.PUSH);
		add.setText("Add");
		add.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				Person p = new Person();
				p.setFirstName("Test");
				p.setLastName("Test");
				input.add(p);
			}
		});
	}

	protected void createExampleData(List<Person> persons) {
		Person p = new Person();
		p.setFirstName("Joe");
		p.setLastName("Darcey");
		persons.add(p);
		p = new Person();
		p.setFirstName("Jim");
		p.setLastName("Knopf");
		persons.add(p);
		p = new Person();
		p.setFirstName("Jim");
		p.setLastName("Bean");
		persons.add(p);
	}

	@Override
	public void setFocus() {

	}

}

			

In this example the UI will be updated if you delete and element or add an element to the collection. Run this example and test it.

4.3. JFace Tableviewer

Similar to above you can use Data Binding to bind data to a table. Create another RCP project "de.vogella.databinding.person.tableviewer" similar to the listviewer example.