blob: afdde9bf3d8fea8a8c11371cc6fa1a0584dc3199 [file] [log] [blame]
/*******************************************************************************
* 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 124684)
******************************************************************************/
package org.eclipse.jface.examples.databinding.snippets;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.ComputedValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
/**
* Snippet 018: Binding to the checked elements in a CheckboxTableViewer.
*/
public class Snippet018CheckboxTableViewerCheckedSelection {
public static void main(String[] args) {
// The SWT event loop
final Display display = Display.getDefault();
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {
ViewModel viewModel = createSampleModel();
Shell shell = new View(viewModel).createShell();
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
}
});
display.dispose();
}
private static ViewModel createSampleModel() {
ViewModel viewModel = new ViewModel();
Person stan = createPerson("Stan");
Person kyle = createPerson("Kyle");
Person eric = createPerson("Eric");
Person kenny = createPerson("Kenny");
Person wendy = createPerson("Wendy");
Person butters = createPerson("Butters");
setFriends(stan, new Person[] { kyle, eric, kenny, wendy });
setFriends(kyle, new Person[] { stan, eric, kenny });
setFriends(eric, new Person[] { eric });
setFriends(kenny, new Person[] { stan, kyle, eric });
setFriends(wendy, new Person[] { stan });
setFriends(butters, new Person[0]);
Person[] people = new Person[] { stan, kyle, eric, kenny, wendy,
butters };
viewModel.setPeople(Arrays.asList(people));
return viewModel;
}
private static Person createPerson(String name) {
Person person = new Person();
person.setName(name);
return person;
}
private static void setFriends(Person person, Person[] friends) {
person.setFriends(new HashSet(Arrays.asList(friends)));
}
// 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);
}
}
// The data model class.
static class Person extends AbstractModelObject {
private String name;
private Set friends = new HashSet();
public String getName() {
return name;
}
public void setName(String name) {
firePropertyChange("name", this.name, this.name = name);
}
public Set getFriends() {
return new HashSet(friends);
}
public void setFriends(Set friends) {
firePropertyChange("friends", this.friends,
this.friends = new HashSet(friends));
}
public String toString() {
return name;
}
}
// The View's model--the root of our Model graph for this particular GUI.
//
// Typically each View class has a corresponding ViewModel class.
//
// The ViewModel is responsible for getting the objects to edit from the
// data access tier. Since this snippet doesn't have any persistent objects
// to retrieve, this ViewModel just instantiates a model object to edit.
static class ViewModel extends AbstractModelObject {
private List people = new ArrayList();
public List getPeople() {
return new ArrayList(people);
}
public void setPeople(List people) {
firePropertyChange("people", this.people,
this.people = new ArrayList(people));
}
}
// The GUI view
static class View {
private ViewModel viewModel;
private Shell shell;
private Button addPersonButton;
private Button removePersonButton;
private TableViewer peopleViewer;
private Text personName;
private CheckboxTableViewer friendsViewer;
public View(ViewModel viewModel) {
this.viewModel = viewModel;
}
public Shell createShell() {
// Build a UI
final Display display = Display.getCurrent();
shell = new Shell(display);
createUI(shell);
// Bind UI
bindUI();
// Open and return the Shell
shell.setSize(shell.computeSize(400, SWT.DEFAULT));
shell.open();
return shell;
}
private void createUI(Shell shell) {
shell.setText("Binding checked elements in CheckboxTableViewer");
shell.setLayout(new GridLayout(2, false));
new Label(shell, SWT.NONE).setText("People");
Composite buttons = new Composite(shell, SWT.NONE);
GridDataFactory.swtDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(
buttons);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(true)
.applyTo(buttons);
addPersonButton = new Button(buttons, SWT.PUSH);
addPersonButton.setText("Add");
GridDataFactory.fillDefaults().applyTo(addPersonButton);
removePersonButton = new Button(buttons, SWT.PUSH);
removePersonButton.setText("Remove");
GridDataFactory.fillDefaults().applyTo(removePersonButton);
Composite peopleComposite = new Composite(shell, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(
peopleComposite);
TableColumnLayout peopleColumnLayout = new TableColumnLayout();
peopleComposite.setLayout(peopleColumnLayout);
peopleViewer = new TableViewer(peopleComposite, SWT.SINGLE
| SWT.BORDER | SWT.FULL_SELECTION);
Table peopleTable = peopleViewer.getTable();
peopleTable.setHeaderVisible(true);
peopleTable.setLinesVisible(true);
TableColumn nameColumn = new TableColumn(peopleTable, SWT.NONE);
nameColumn.setText("Name");
peopleColumnLayout.setColumnData(nameColumn,
new ColumnWeightData(1));
TableColumn friendsColumn = new TableColumn(peopleTable, SWT.NONE);
friendsColumn.setText("Friends");
peopleColumnLayout.setColumnData(friendsColumn,
new ColumnWeightData(3));
new Label(shell, SWT.NONE).setText("Name");
personName = new Text(shell, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false)
.applyTo(personName);
new Label(shell, SWT.NONE).setText("Friends");
Composite friendsComposite = new Composite(shell, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).applyTo(
friendsComposite);
TableColumnLayout friendsColumnLayout = new TableColumnLayout();
friendsComposite.setLayout(friendsColumnLayout);
friendsViewer = CheckboxTableViewer.newCheckList(friendsComposite,
SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
Table friendsTable = friendsViewer.getTable();
friendsTable.setHeaderVisible(true);
friendsTable.setLinesVisible(true);
TableColumn friendNameColumn = new TableColumn(friendsTable,
SWT.NONE);
friendNameColumn.setText("Name");
friendsColumnLayout.setColumnData(friendNameColumn,
new ColumnWeightData(1));
GridDataFactory.fillDefaults().grab(true, true).applyTo(
friendsViewer.getTable());
}
private void bindUI() {
DataBindingContext dbc = new DataBindingContext();
final IObservableList people = BeansObservables.observeList(Realm
.getDefault(), viewModel, "people");
addPersonButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
InputDialog dlg = new InputDialog(shell, "Add Person",
"Enter name:", "<Name>", new IInputValidator() {
public String isValid(String newText) {
if (newText == null
|| newText.length() == 0)
return "Name cannot be empty";
return null;
}
});
if (dlg.open() == Window.OK) {
Person person = new Person();
person.setName(dlg.getValue());
people.add(person);
peopleViewer.setSelection(new StructuredSelection(
person));
}
}
});
removePersonButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
IStructuredSelection selected = (IStructuredSelection) peopleViewer
.getSelection();
if (selected.isEmpty())
return;
Person person = (Person) selected.getFirstElement();
if (MessageDialog.openConfirm(shell, "Remove person",
"Remove " + person.getName() + "?"))
people.remove(person);
}
});
ObservableListContentProvider peopleContentProvider = new ObservableListContentProvider();
peopleViewer.setContentProvider(peopleContentProvider);
peopleViewer.setLabelProvider(new ObservableMapLabelProvider(
BeansObservables.observeMaps(peopleContentProvider
.getKnownElements(), Person.class, new String[] {
"name", "friends" })));
peopleViewer.setInput(people);
final IObservableValue selectedPerson = ViewersObservables
.observeSingleSelection(peopleViewer);
IObservableValue personSelected = new ComputedValue(Boolean.TYPE) {
protected Object calculate() {
return Boolean.valueOf(selectedPerson.getValue() != null);
}
};
dbc.bindValue(SWTObservables.observeEnabled(removePersonButton),
personSelected, null, null);
dbc.bindValue(SWTObservables.observeEnabled(friendsViewer
.getTable()), personSelected, null, null);
dbc.bindValue(SWTObservables.observeText(personName, SWT.Modify),
BeansObservables.observeDetailValue(Realm.getDefault(),
selectedPerson, "name", String.class), null, null);
ObservableListContentProvider friendsContentProvider = new ObservableListContentProvider();
friendsViewer.setContentProvider(friendsContentProvider);
friendsViewer.setLabelProvider(new ObservableMapLabelProvider(
BeansObservables.observeMap(friendsContentProvider
.getKnownElements(), Person.class, "name")));
friendsViewer.setInput(people);
dbc.bindSet(ViewersObservables.observeCheckedElements(
friendsViewer, Person.class), BeansObservables
.observeDetailSet(Realm.getDefault(), selectedPerson,
"friends", Person.class), null, null);
}
}
}