As a newcomer to the Instantiations Data Binding GUI, and Eclipse Data Binding in general, I'm beating my head against the wall with trying to get a table viewer to update detail fields (which works easily), and the detail fields to update the table as they're being edited. I've seen this work quite well in the PhoneBook example, but got to the point where TableViewer selections update the detail fields, and detail editing definitely changes the underlying model (checked with System.out statements and inspection in the debugger), but the TableViewer fields don't update while the detail is being edited.
I've distilled this down to the most simple example I could make--an SWT shell with a table viewer, two detail fields, a very simple underlying data model, and the appropriate (as far as I can determine) bindings. Can anyone point out what I'm sure is a very simple missing piece to this puzzle?
Here are the three classes:
SWT Shell:
- Code: Select all
package lawrence;
import java.util.ArrayList;
import java.util.List;
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.WritableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
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.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import lawrence.SimpleModel;
public class SimpleTroubleShell extends Shell {
private DataBindingContext m_bindingContext;
private TableViewer simpleTableViewer;
private Text integerText;
private Text nameText;
private Table table;
public List<SimpleModel> smList = new ArrayList<SimpleModel>();
public void initializeModels() {
smList.add(new SimpleModel("First", 1));
smList.add(new SimpleModel("Second", 2));
smList.add(new SimpleModel("Third", 3));
}
public static void main(String args[]) {
Display display = Display.getDefault();
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {
try {
Display display = Display.getDefault();
SimpleTroubleShell shell = new SimpleTroubleShell(display,
SWT.SHELL_TRIM);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SimpleTroubleShell(Display display, int style) {
super(display, style);
createContents();
setLayout(new FillLayout());
}
protected void createContents() {
setText("Simple Trouble Demonstration");
setSize(500, 375);
final SashForm sashForm = new SashForm(this, SWT.VERTICAL);
final Composite topComposite = new Composite(sashForm, SWT.NONE);
topComposite.setLayout(new FillLayout());
simpleTableViewer = new TableViewer(topComposite, SWT.BORDER);
table = simpleTableViewer.getTable();
table.setLinesVisible(true);
table.setHeaderVisible(true);
final TableColumn nameColumn = new TableColumn(table, SWT.NONE);
nameColumn.setWidth(157);
nameColumn.setText("Name");
final TableColumn integerColumn = new TableColumn(table, SWT.NONE);
integerColumn.setWidth(100);
integerColumn.setText("Integer");
final Composite bottomComposite = new Composite(sashForm, SWT.NONE);
final GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
bottomComposite.setLayout(gridLayout);
final Label nameLabel = new Label(bottomComposite, SWT.NONE);
nameLabel.setText("Name");
nameText = new Text(bottomComposite, SWT.BORDER);
final GridData gd_nameText = new GridData(SWT.FILL, SWT.CENTER, true, false);
nameText.setLayoutData(gd_nameText);
final Label integerLabel = new Label(bottomComposite, SWT.NONE);
integerLabel.setText("Integer");
integerText = new Text(bottomComposite, SWT.BORDER);
final GridData gd_integerText = new GridData(SWT.FILL, SWT.CENTER, true, false);
integerText.setLayoutData(gd_integerText);
sashForm.setWeights(new int[] {1, 1 });
initializeModels();
m_bindingContext = initDataBindings();
//
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
protected DataBindingContext initDataBindings() {
IObservableValue simpleTableViewerSelectionObserveSelection_1 = ViewersObservables.observeSingleSelection(simpleTableViewer);
IObservableValue simpleTableViewerSelectionObserveSelection = ViewersObservables.observeSingleSelection(simpleTableViewer);
IObservableValue integerTextTextObserveWidget = SWTObservables.observeText(integerText, SWT.Modify);
IObservableValue nameTextTextObserveWidget = SWTObservables.observeText(nameText, SWT.Modify);
IObservableValue simpleTableViewerIntObserveDetailValue = BeansObservables.observeDetailValue(Realm.getDefault(), simpleTableViewerSelectionObserveSelection_1, "int", int.class);
IObservableValue simpleTableViewerNameObserveDetailValue = BeansObservables.observeDetailValue(Realm.getDefault(), simpleTableViewerSelectionObserveSelection, "name", java.lang.String.class);
//
ObservableListContentProvider simpleTableViewerContentProviderList = new ObservableListContentProvider();
simpleTableViewer.setContentProvider(simpleTableViewerContentProviderList);
//
IObservableMap[] simpleTableViewerLabelProviderMaps = BeansObservables.observeMaps(simpleTableViewerContentProviderList.getKnownElements(), SimpleModel.class, new String[]{"name", "int"});
simpleTableViewer.setLabelProvider(new ObservableMapLabelProvider(simpleTableViewerLabelProviderMaps));
//
WritableList smListWritableList = new WritableList(smList, SimpleModel.class);
simpleTableViewer.setInput(smListWritableList);
//
DataBindingContext bindingContext = new DataBindingContext();
//
bindingContext.bindValue(simpleTableViewerNameObserveDetailValue, nameTextTextObserveWidget, null, null);
bindingContext.bindValue(simpleTableViewerIntObserveDetailValue, integerTextTextObserveWidget, null, null);
//
return bindingContext;
}
}
Simple data model:
- Code: Select all
package lawrence;
import lawrence.AbstractModelObject;
public class SimpleModel extends AbstractModelObject {
public String myName;
public int myInt;
public SimpleModel() {
super();
}
public SimpleModel(String newName, int newInt) {
this();
this.setName(newName);
this.setInt(newInt);
}
public void setName(String newName) {
String oldValue = myName;
myName = newName;
firePropertyChange("myName", oldValue, myName);
}
public String getName() {
return myName;
}
public void setInt(int newInt) {
int oldValue = myInt;
myInt = newInt;
firePropertyChange("myInt", oldValue, myInt);
}
public int getInt() {
return myInt;
}
}
Abstract Model with Java Bean support:
- Code: Select all
package lawrence;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public abstract class AbstractModelObject {
private final PropertyChangeSupport m_propertyChangeSupport = new PropertyChangeSupport(this);
////////////////////////////////////////////////////////////////////////////
//
// Property Support
//
////////////////////////////////////////////////////////////////////////////
public void addPropertyChangeListener(PropertyChangeListener listener) {
m_propertyChangeSupport.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
m_propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
m_propertyChangeSupport.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
m_propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
}
public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
m_propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
}
Hopefully this isn't a frequently asked question--I've been searching for some time for help.
Thanks to any kind souls in advance,
Lawrence