blob: 665a9b9a0f4992d5061a574ebbc93b807fcf9ecc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2009 Matthew Hall and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthew Hall - initial API and implementation (bug 247997)
* Matthew Hall - bugs 261843, 260337, 265561
******************************************************************************/
package org.eclipse.xwt.tests.snipppets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.set.SetDiff;
import org.eclipse.core.databinding.observable.value.ComputedValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.INativePropertyListener;
import org.eclipse.core.databinding.property.IProperty;
import org.eclipse.core.databinding.property.ISimplePropertyListener;
import org.eclipse.core.databinding.property.NativePropertyListener;
import org.eclipse.core.databinding.property.set.DelegatingSetProperty;
import org.eclipse.core.databinding.property.set.ISetProperty;
import org.eclipse.core.databinding.property.set.SimpleSetProperty;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.databinding.viewers.ViewerSupport;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
/**
* @since 3.2
*
*/
public class Snippet026AnonymousBeanProperties {
private ComboViewer statusViewer;
private Combo combo;
private Text nameText;
private TreeViewer contactViewer;
public static void main(String[] args) {
Display display = new Display();
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {
try {
Snippet026AnonymousBeanProperties window = new Snippet026AnonymousBeanProperties();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private ApplicationModel model;
private Shell shell;
private Tree tree;
// Minimal JavaBeans support
public static abstract class AbstractModelObject {
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName,
listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyName,
listener);
}
protected void firePropertyChange(String propertyName, Object oldValue,
Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue,
newValue);
}
}
public static class ContactGroup extends AbstractModelObject implements
Comparable {
private String name;
private Set contacts = new TreeSet();
ContactGroup(String name) {
this.name = checkNull(name);
}
private String checkNull(String string) {
if (string == null)
throw new NullPointerException();
return string;
}
public String getName() {
return name;
}
public void setName(String name) {
firePropertyChange("name", this.name, this.name = checkNull(name));
}
public Set getContacts() {
return new TreeSet(contacts);
}
public void addContact(Contact contact) {
Set oldValue = getContacts();
contacts.add(contact);
Set newValue = getContacts();
firePropertyChange("contacts", oldValue, newValue);
}
public void removeContact(Contact contact) {
Set oldValue = getContacts();
contacts.remove(contact);
Set newValue = getContacts();
firePropertyChange("contacts", oldValue, newValue);
}
public int compareTo(Object o) {
ContactGroup that = (ContactGroup) o;
return this.name.compareTo(that.name);
}
}
public static class Contact extends AbstractModelObject implements
Comparable {
private String name;
private String status;
private String checkNull(String string) {
if (string == null)
throw new NullPointerException();
return string;
}
public Contact(String name, String status) {
this.name = checkNull(name);
this.status = checkNull(status);
}
public String getName() {
return name;
}
public void setName(String name) {
firePropertyChange("name", this.name, this.name = checkNull(name));
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
firePropertyChange("status", this.status,
this.status = checkNull(status));
}
public int compareTo(Object o) {
Contact that = (Contact) o;
int result = this.name.compareTo(that.name);
if (result == 0)
result = this.status.compareTo(that.status);
return result;
}
}
public static class ApplicationModel extends AbstractModelObject {
private Set groups = new TreeSet();
public Set getGroups() {
return new TreeSet(groups);
}
public void setGroups(Set groups) {
Set oldValue = getGroups();
this.groups = new TreeSet(groups);
Set newValue = getGroups();
firePropertyChange("groups", oldValue, newValue);
}
}
/**
* Set property for the "contacts" property of a ContactGroup. Since
* ContactGroup does not have a setContacts() method we have to write our
* own property to apply set changes incrementally through the addContact
* and removeContact methods.
*/
public static class ContactGroupContactsProperty extends SimpleSetProperty {
public Object getElementType() {
return Contact.class;
}
protected Set doGetSet(Object source) {
if (source == null)
return Collections.EMPTY_SET;
return ((ContactGroup) source).getContacts();
}
protected void doSetSet(Object source, Set set, SetDiff diff) {
ContactGroup group = (ContactGroup) source;
for (Iterator it = diff.getRemovals().iterator(); it.hasNext();) {
Contact contact = (Contact) it.next();
group.removeContact(contact);
}
for (Iterator it = diff.getAdditions().iterator(); it.hasNext();) {
Contact contact = (Contact) it.next();
group.addContact(contact);
}
}
public INativePropertyListener adaptListener(
final ISimplePropertyListener listener) {
return new Listener(this, listener);
}
private class Listener extends NativePropertyListener implements
PropertyChangeListener {
Listener(IProperty property, ISimplePropertyListener listener) {
super(property, listener);
}
public void propertyChange(PropertyChangeEvent evt) {
fireChange(evt.getSource(), null);
}
protected void doAddTo(Object source) {
((ContactGroup) source).addPropertyChangeListener("contacts",
this);
}
protected void doRemoveFrom(Object source) {
((ContactGroup) source).removePropertyChangeListener(
"contacts", this);
}
}
}
public void open() {
model = createDefaultModel();
final Display display = Display.getDefault();
createContents();
bindUI();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
private static final String[] statuses = new String[] { "Online", "Idle",
"Busy", "Offline" };
/**
* @return
*/
private ApplicationModel createDefaultModel() {
ContactGroup swtGroup = new ContactGroup("SWT");
swtGroup.addContact(new Contact("Steve Northover", "Busy"));
swtGroup.addContact(new Contact("Grant Gayed", "Online"));
swtGroup.addContact(new Contact("Veronika Irvine", "Offline"));
swtGroup.addContact(new Contact("Mike Wilson", "Online"));
swtGroup.addContact(new Contact("Christophe Cornu", "Idle"));
swtGroup.addContact(new Contact("Lynne Kues", "Online"));
swtGroup.addContact(new Contact("Silenio Quarti", "Idle"));
ContactGroup jdbGroup = new ContactGroup("JFace Data Binding");
jdbGroup.addContact(new Contact("Boris Bokowski", "Online"));
jdbGroup.addContact(new Contact("Matthew Hall", "Idle"));
Set groups = new TreeSet();
groups.add(swtGroup);
groups.add(jdbGroup);
ApplicationModel model = new ApplicationModel();
model.setGroups(groups);
return model;
}
/**
* Create nameMap of the window
*/
protected void createContents() {
shell = new Shell();
shell.setSize(379, 393);
shell.setText("Snippet026AnonymousBeanProperties");
final GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 4;
shell.setLayout(gridLayout);
contactViewer = new TreeViewer(shell, SWT.BORDER);
tree = contactViewer.getTree();
tree.setHeaderVisible(true);
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1));
final TreeColumn nameColumn = new TreeColumn(tree, SWT.NONE);
nameColumn.setWidth(163);
nameColumn.setText("Name");
final TreeColumn newColumnTreeColumn = new TreeColumn(tree, SWT.NONE);
newColumnTreeColumn.setWidth(100);
newColumnTreeColumn.setText("Status");
final Label nameLabel = new Label(shell, SWT.NONE);
nameLabel.setText("Name");
nameText = new Text(shell, SWT.BORDER);
final GridData gd_nameText = new GridData(SWT.FILL, SWT.CENTER, true,
false);
nameText.setLayoutData(gd_nameText);
final Label statusLabel = new Label(shell, SWT.NONE);
statusLabel.setLayoutData(new GridData());
statusLabel.setText("Status");
statusViewer = new ComboViewer(shell, SWT.READ_ONLY);
combo = statusViewer.getCombo();
combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
}
private void bindUI() {
ISetProperty treeChildrenProperty = new DelegatingSetProperty() {
ISetProperty modelGroups = BeanProperties.set(
ApplicationModel.class, "groups");
ISetProperty groupContacts = BeanProperties.set(ContactGroup.class,
"contacts");
protected ISetProperty doGetDelegate(Object source) {
if (source instanceof ApplicationModel)
return modelGroups;
if (source instanceof ContactGroup)
return groupContacts;
return null;
}
};
ViewerSupport.bind(contactViewer, model, treeChildrenProperty,
BeanProperties.values(new String[] { "name", "status" }));
contactViewer.expandAll();
final IObservableValue selection = ViewerProperties.singleSelection()
.observe(contactViewer);
DataBindingContext dbc = new DataBindingContext();
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(nameText),
BeanProperties.value("name").observeDetail(selection));
statusViewer.setContentProvider(new ArrayContentProvider());
statusViewer.setInput(statuses);
dbc.bindValue(ViewerProperties.singleSelection().observe(statusViewer),
BeanProperties.value("status").observeDetail(selection));
dbc.bindValue(WidgetProperties.enabled().observe(
statusViewer.getControl()), new ComputedValue() {
protected Object calculate() {
return Boolean.valueOf(selection.getValue() instanceof Contact);
}
});
}
}