[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Newsgroup Home]
|
[news.eclipse.platform] Re: Does jface databinding support treeviewer?
|
hao wrote:
HI,
I already did that but still get error. Please see the source code on my
post of treeviewer databinding error. I think the problem is that the
label provider is not generated correctly. Do you have any idea on how
to create the label provider?
thanks!
I see the problem. In the code that sets up the label providers, you
are using BeansObservables.observeMaps() and specifying
PersonPhone.class as the bean class. However PersonPhoneGroup instances
are not instanceof PersonPhone. Bean properties are not duck-typed so
there has to be common superclass for them.
You can subclass ListeningLabelProvider to accommodate viewers where
elements do not have properties in common. I suggest writing your own
subclass of ListeningLabelProvider which delegates to another label
provider based on the runtime type of the element:
class PersonGroupLabelProvider extends ListeningLabelProvider
implements ITableLabelProvider {
boolean initialized;
IObservableSet personPhoneKnownElements;
IObservableSet personGroupKnownElements;
ObservableMapLabelProvider personPhoneLabelProvider;
ObservableMapLabelProvider personPhoneGroupLabelProvider;
PersonGroupLabelProvider(IObservableSet knownElements) {
super(knownElements);
// Cannot init in the constructor because superconstructor calls
// addListenerTo. That aspect should probably be changed...
}
private void init() {
if (!initialized) {
personPhoneKnownElements = new WritableSet();
IObservableMap[] maps = BeansObservables.observeMaps(
personPhoneKnownElements,
PersonPhone.class,
new String[] { "name", "email", "phone", "mobilePhone1",
"mobilePhone2" } );
personPhoneLabelProvider = new ObservableMapLabelProvider(maps)
personPhoneGroupKnownElements = new WritableSet();
maps = BeansObservables.observeMaps(
personPhoneGroupKnownElements,
PersonPhoneGroup,
new String[] { "name" } );
personPhoneGroupLabelProvider =
new ObservableMapLabelProvider(maps);
initialized = true;
}
}
protected void addListenerTo(Object element) {
init();
if (element instanceof PersonPhone)
personPhoneKnownElements.add(element);
if (element instanceof PersonPhoneGroup)
personPhoneGroupKnownElements.add(element);
}
protected void removeListenerFrom(Object element) {
init();
if (element instanceof PersonPhone)
personPhoneKnownElements.remove(element);
if (element instanceof PersonPhoneGroup)
personPhoneGroupKnownElements.remove(element);
}
public void addListener(ILabelProviderListener listener) {
init();
personPhoneLabelProvider.addListener(listener);
personPhoneGroupLabelProvider.addListener(listener);
}
public void removeListener(ILabelProviderListener listener) {
init();
personPhoneLabelProvider.removeListener(listener);
personPhoneGroupLabelProvider.removeListener(listener);
}
// Implement the ITableLabelProvider methods so they delegate
// to personPhoneLabelProvider if the element is an instance of
// PersonPhone, or to personPhoneGroupLabelProvider if the element is
// an instanceof PersonPhoneGroup.
}
I also noticed that PersonPhoneGroup has several of the PersonPhone
properties, but they are not used. With the above changes you could
eliminate those.
Or you could just go the easy route and extract a common interface
between the two classes, then change the call to
BeansObservables.observeMaps() so it passes the extracted interface
instead of PersonPhone.class:
interface IPersonPhone {
public void setName(String name);
public String getName();
public void setEmail(String email);
// etc
}
Let us know what you decide to do, and how it goes.
Matthew