view org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet026AnonymousBeanProperties.d @ 99:5d5bd660917f

build some databind snippets
author Frank Benoit <benoit@tionex.de>
date Wed, 22 Apr 2009 18:59:26 +0200
parents 6086085e153d
children e884642ad36e
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2008 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
 ******************************************************************************/

module org.eclipse.jface.examples.databinding.snippets.Snippet026AnonymousBeanProperties;

import java.lang.all;

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 contents 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 bool.valueOf(selection.getValue() instanceof Contact);
            }
        });
    }
}
void main( String[] args ){
    Snippet026AnonymousBeanProperties.main(args);
}