Decipher Eclipse Architecture: IAdaptable – Part 3 – Show Properties for Items in a View

This example shows how IAdaptable is used in Eclipse in a real example. To get a taste of how Adapter design pattern works in Eclipse, go to those posts: post1 post2.

Suppose you have created a view by using eclipse "Extension wizard". (If you do not know this, try to play around and get this done.)

And Now change code in SampleView.java to be the following:

package adapterview.views;
 
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.*;
import org.eclipse.swt.SWT;
 
public class SampleView extends ViewPart {
 
	private TableViewer viewer;
 
	class ViewLabelProvider extends LabelProvider implements
			ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			TestItem testItem = (TestItem) obj;
			return testItem.getSummary();
		}
 
		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}
 
		public Image getImage(Object obj) {
			return PlatformUI.getWorkbench().getSharedImages()
					.getImage(ISharedImages.IMG_OBJ_ELEMENT);
		}
	}
 
	/**
	 * This is a callback that will allow us to create the viewer and initialize it.
	 */
 
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		viewer.setContentProvider(new ArrayContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		getSite().setSelectionProvider(viewer);
		viewer.setInput(getElements());
 
	}
 
/**
	 * Passing the focus request to the viewer's control.
	 */
 
	public void setFocus() {
		viewer.getControl().setFocus();
	}
 
	// Build up a simple data model
	private TestItem[] getElements() {
		TestItem[] testItems = new TestItem[2];
		TestItem testItem = new TestItem();
		testItem.setSummary("First Item");
		testItem.setDescription("A very good description");
		testItems[0] = testItem;
		testItem = new TestItem();
		testItem.setSummary("Second Item");
		testItem.setDescription("Another very good description");
		testItems[1] = testItem;
		return testItems;
	}
}

TestItem.java

package adapterview.views;
public class TestItem {
	private String summary;
	private String description;
	public String getSummary() {
		return summary;
	}
	public void setSummary(String summary) {
		this.summary = summary;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
}

Basically, this will create a view and shown like this figure.

What if I want to show the Summary and Description in a property view when each item is clicked? You may think about changing some part of the code in the SampleView, but Eclipse platform is amazing and there is no need to change in this class.

What we need is to add an adapter for TestItem Class.

Now add the following snippet to the plugin.xml file.

<extension
         point="org.eclipse.core.runtime.adapters">
      <factory
            adaptableType="adapterview.views.TestItem"
            class="adapterplace.TestItemAdapterFactory">
         <adapter
               type="org.eclipse.ui.views.properties.IPropertySource">
         </adapter>
      </factory>
</extension>

This declares the following three classes:

1. adaptableType is TestItem
2. the factory to create adapter for adaptableType(TestItem) is TestItemAdapterFactory
3. adapter is IPropertySource which is required for property view to show properties.

Recall the apple and orange example in my previous post, now here we want to go from TestItem to IPropertySource.

File file hierarchy is like this:

TestItemAdapterFactory.java

package adapterplace;
 
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.ui.views.properties.IPropertySource;
import adapterview.views.*;
 
public class TestItemAdapterFactory implements IAdapterFactory {
 
	@Override
	public Object getAdapter(Object adaptableObject, Class adapterType) {
		if (adapterType== IPropertySource.class && adaptableObject instanceof TestItem){
			return new TestItemAdapter((TestItem) adaptableObject);
		}
		return null;
	}
 
	@Override
	public Class[] getAdapterList() {
		// TODO Auto-generated method stub
		return null;
	}
}

TestItemAdapter.java - this class wrap a TestItem object with IPropertySource's methods, which in turned are required by Property view.

package adapterplace;
 
import adapterview.views.TestItem;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
 
 
public class TestItemAdapter implements IPropertySource {
	private final TestItem testItem;
 
	public TestItemAdapter(TestItem testItem) {
		this.testItem = testItem;
	}
 
 
	@Override
	public boolean isPropertySet(Object id) {
		return false;
	}
 
	@Override
	public Object getEditableValue() {
		return this;
	}
 
	@Override
	public IPropertyDescriptor[] getPropertyDescriptors() {
 
		return new IPropertyDescriptor[] {
				new TextPropertyDescriptor("summary", "Summary"),
				new TextPropertyDescriptor("description", "Description") };
	}
 
	@Override
	public Object getPropertyValue(Object id) {
		if (id.equals("summary")) {
			return testItem.getSummary();
		}
		if (id.equals("description")) {
			return testItem.getDescription();
		}
		return null;
	}
 
	@Override
	public void resetPropertyValue(Object id) {
 
	}
 
	@Override
	public void setPropertyValue(Object id, Object value) {
		String s = (String) value;
		if (id.equals("summary")) {
			testItem.setSummary(s);
		}
		if (id.equals("description")) {
			testItem.setDescription(s);
		}
	}
}

Result: when an item in the sample view is selected, property view shows its property.

Reference:

IPropertySource

Category >> Architecture & Design  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

Leave a comment

*