Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » JFace » How to correctly write a custom widget based on existing widgets
How to correctly write a custom widget based on existing widgets [message #511726] Tue, 02 February 2010 16:30 Go to next message
Lothar Werzinger is currently offline Lothar WerzingerFriend
Messages: 153
Registered: July 2009
Location: Bay Area
Senior Member
--nextPart3122358.8WjPxlS8eG
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8Bit

Hi,

I am trying to build specialized widgets from existing widgets to allow
efficient databinding. My first experimental widget is a combo that selects
an EObject (EMF object) from an EList.

The widget works as expected, but I am not a SWT/Jface specialist and
therefore I would like to know if the implementation is correct the way I
did it.
I would appreciate if anyone of the SWT/Jface gurus could take a look.

I attached the widget in question.

Here's a snippet on how I use it in my sample code:

IWidgetValueProperty comboSelectionProp =
new EListComboSelectionProperty();
IWidgetListProperty comboItemsProp = new EListComboItemsProperty();

dbc.bindList(comboItemsProp.observe(module), EMFEditProperties.list(
domain,
FeaturePath.fromList(
AdministrationPackage.Literals.MODULE_ACCESS__USER,
AdministrationPackage.Literals.USER__MODEL,
AdministrationPackage.Literals.MODEL__MODULES)).observeDetai l(
AccessRightForm.this));

dbc.bindValue(comboSelectionProp.observe(module), EMFEditProperties
.value(domain,
AdministrationPackage.Literals.MODULE_ACCESS__MODULE)
.observeDetail(AccessRightForm.this));



Thanks in advance

Lothar


--nextPart3122358.8WjPxlS8eG
Content-Type: text/x-java; name="EListComboItemsProperty.java"
Content-Transfer-Encoding: 8Bit
Content-Disposition: attachment; filename="EListComboItemsProperty.java"

package biz.tradescape.mmt.ui.databinding;

import java.util.List;

import org.eclipse.core.databinding.observable.list.ListDiff;
import org.eclipse.core.databinding.property.INativePropertyListene r;
import org.eclipse.core.databinding.property.ISimplePropertyListene r;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.databinding.swt.WidgetListProperty;

import biz.tradescape.mmt.ui.widgets.EListCombo;

public class EListComboItemsProperty
extends
WidgetListProperty
{
@SuppressWarnings("rawtypes")
@Override
protected List doGetList(Object source)
{
EListCombo combo = (EListCombo) source;
return combo.getItems();
}

@SuppressWarnings(
{
"rawtypes", "unchecked"
})
@Override
protected void doSetList(Object source, List list, ListDiff diff)
{
EListCombo combo = (EListCombo) source;
combo.setItems((List<? extends EObject>) list);
}

@Override
public INativePropertyListener adaptListener(ISimplePropertyListener listener)
{
return null;
}

@Override
public Object getElementType()
{
return EList.class;
}
}


--nextPart3122358.8WjPxlS8eG
Content-Type: text/x-java; name="EListCombo.java"
Content-Transfer-Encoding: 8Bit
Content-Disposition: attachment; filename="EListCombo.java"

package biz.tradescape.mmt.ui.widgets;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

import biz.tradescape.mmt.ui.Activator;

public class EListCombo
extends
Composite
{
private Combo combo;
private List<EObject> items = new ArrayList<EObject>();

private Method method;

private class ListenerProxy
implements
Listener
{
int eventType;
Listener listener;

public ListenerProxy(
int eventType, Listener handler)
{
this.eventType = eventType;
this.listener = handler;
proxyListeners.add(this);
}

@Override
public void handleEvent(Event event)
{
event.widget = EListCombo.this;
listener.handleEvent(event);
}
};

private List<ListenerProxy> proxyListeners = new ArrayList<ListenerProxy>();

public EListCombo(
Composite parent, int style)
{
super(parent, SWT.NONE);
setLayout(new FillLayout());
combo = new Combo(this, style);
}

@Override
public void addListener(int eventType, Listener handler)
{
ListenerProxy proxy = null;
synchronized (proxyListeners)
{
proxy = new ListenerProxy(eventType, handler);
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat.format(
"Proxy for handler {0}, eventType {1} added", handler, eventType));
}
combo.addListener(eventType, proxy);
}

@Override
public void removeListener(int eventType, Listener handler)
{
ListenerProxy proxy = null;
synchronized (proxyListeners)
{
for (ListenerProxy check : proxyListeners)
{
if (check.eventType == eventType && check.listener == handler)
{
proxy = check;
proxyListeners.remove(proxy);
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat
.format(
"Proxy for handler {0}, eventType {1} removed", handler,
eventType));
break;
}
}
}
if (proxy != null)
combo.removeListener(eventType, proxy);
else
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat.format(
"Proxy for handler {0}, eventType {1} is null", handler, eventType));
}

public int getSelectionIndex()
{
int result = combo.getSelectionIndex();
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat.format(
"getSelectionIndex result={0}", result));
return result;
}

public EObject getItem(int index)
{
EObject result = items.get(index);
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat.format(
"getItem result={0}", result));
return result;
}

public List<? extends EObject> getItems()
{
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat.format(
"getItems {0} ({1})", items.size(), items));
return Collections.unmodifiableList(items);
}

public void setItems(List<? extends EObject> list)
{
if (items == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
items.clear();
items.addAll(list);
Activator.logTrace(this.getClass().getSimpleName(), MessageFormat.format(
"setItems {0} ({1})", items.size(), items));
updateCombo();
}

public void select(EObject object)
{
combo.select(items.indexOf(object));
}

public void setItemTextMethod(Method method)
{
this.method = method;
}

private String getText(EObject object)
{
String name = null;

if (method != null)
{
try
{
name = (String) method.invoke(object);
}
catch (IllegalArgumentException e)
{
; // ignore
}
catch (IllegalAccessException e)
{
; // ignore
}
catch (InvocationTargetException e)
{
; // ignore
}
}

if (name == null)
name = object.toString();

return name;
}

private void updateCombo()
{
combo.removeAll();

int index = 0;
for (EObject item : items)
{
String text = getText(item);
combo.add(text, index++);
}
}

}


--nextPart3122358.8WjPxlS8eG
Content-Type: text/x-java; name="EListComboSelectionProperty.java"
Content-Transfer-Encoding: 8Bit
Content-Disposition: attachment; filename="EListComboSelectionProperty.java"

package biz.tradescape.mmt.ui.databinding;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.databinding.swt.WidgetValueProperty;
import org.eclipse.swt.SWT;

import biz.tradescape.mmt.ui.widgets.EListCombo;

public class EListComboSelectionProperty
extends
WidgetValueProperty
{
public EListComboSelectionProperty()
{
super(SWT.Modify);
}

@Override
protected Object doGetValue(Object source)
{
EListCombo combo = (EListCombo) source;
int index = combo.getSelectionIndex();
if (index == -1)
return null;
else
return combo.getItem(index);
}

@Override
protected void doSetValue(Object source, Object value)
{
EListCombo combo = (EListCombo) source;
for (Object item : combo.getItems())
{
if (value == item)
{
combo.select((EObject) value);
}
}
}

@Override
public Object getValueType()
{
return EObject.class;
}
}


--nextPart3122358.8WjPxlS8eG--
Re: How to correctly write a custom widget based on existing widgets [message #519026 is a reply to message #511726] Fri, 05 March 2010 18:29 Go to previous message
chengdong is currently offline chengdongFriend
Messages: 17
Registered: July 2009
Junior Member
Instead of creating your own EListCombo, you can use JFace ComboViewer, and provide an ObservableListContentProvider:

Combo combo = new Combo(parent, style);
ComboViewer viewer = new ComboViewer(combo);

myLabelProvider = .... // customize items label
viewer.setLabelProvider(myLabelProvider);

viewer.setContentProvider(ObservableListContentProvider());
IObservableList observableList = ... // create list of observable items
viewer.setInput(observableList);

// bind viewer selection to domain element
IObservable myDomainObservable = ...
dbc.bindValue(ViewerProperties.singleSelection().observe(vie wer), myDomainObservable);


Previous Topic:Why TreeViewer is not intended to be subclassed by clients.
Next Topic:Jface unit tests
Goto Forum:
  


Current Time: Mon Dec 22 18:35:59 GMT 2014

Powered by FUDForum. Page generated in 0.02963 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software