blob: ae070ea631a90e817533541fc246839dfb99fff8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 vogella GmbH and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
******************************************************************************/
package org.eclipse.jface.examples.databinding.snippets;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.sideeffect.ISideEffect;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.jface.databinding.swt.DisplayRealm;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* This snippet shows how to use the {@link ISideEffect} class with conditional
* elements in it.<br/>
* <br/>
* Also see the following part of the ISideEffect's JavaDoc:
*
* <ul>
* <li>The {@link ISideEffect} can self-optimize based on branches in the run
* method. It will remove listeners from any {@link IObservable} which wasn't
* used on the most recent run. In the above example, there is no need to listen
* to the lastName field when showFullNamePreference is false.
* <li>The {@link ISideEffect} will batch changes together and run
* asynchronously. If firstName and lastName change at the same time, the
* {@link ISideEffect} will only run once.
* <li>Since the {@link ISideEffect} doesn't need to be explicitly attached to
* the observables it affects, it is impossible for it to get out of sync with
* the underlying data.
* </ul>
*
* @since 3.2
*
*/
public class SnippetSideEffectConditionalBinding {
public static void main(String[] args) {
Display display = new Display();
Realm.runWithDefault(DisplayRealm.getRealm(display), () -> {
// create the Person model object
Person person = new Person();
final Shell shell = new View(person).createShell();
Display display1 = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display1.readAndDispatch()) {
display1.sleep();
}
}
});
}
// Observable Person model
static class Person {
private WritableValue<String> firstName = new WritableValue<>("Simon", String.class);
private WritableValue<String> lastName = new WritableValue<>("Scholz", String.class);
/**
* @return the person's first name
* @TrackedGetter
*/
public String getFirstName() {
return firstName.getValue();
}
/**
* @param firstName
* The summary to set.
*/
public void setFirstName(String firstName) {
this.firstName.setValue(firstName);
}
/**
* @return Returns the description.
* @TrackedGetter
*/
public String getLastName() {
return lastName.getValue();
}
/**
* @param lastName
* The last name to set.
*/
public void setLastName(String lastName) {
this.lastName.setValue(lastName);
}
}
static class View {
private Person person;
private Text personNameText;
private Button showDescriptionButton;
private Button changeNameButton;
public View(Person person) {
this.person = person;
}
public Shell createShell() {
Display display = Display.getDefault();
Shell shell = new Shell(display);
GridLayoutFactory.swtDefaults().applyTo(shell);
GridDataFactory gridDataFactory = GridDataFactory.fillDefaults().grab(true, false);
personNameText = new Text(shell, SWT.READ_ONLY);
gridDataFactory.applyTo(personNameText);
showDescriptionButton = new Button(shell, SWT.CHECK);
showDescriptionButton.setText("Show full name");
gridDataFactory.applyTo(showDescriptionButton);
changeNameButton = new Button(shell, SWT.PUSH);
changeNameButton.setText("Change Last Name");
gridDataFactory.applyTo(changeNameButton);
changeNameButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// if the showDescriptionButton isn't checked this won't
// cause the ISideEffect to be run
person.setLastName("Xenos");
}
});
bindData();
// Open and return the Shell
shell.pack();
shell.open();
return shell;
}
private void bindData() {
IObservableValue<Boolean> showDescription = WidgetProperties.selection().observe(showDescriptionButton);
// create a conditional ISideEffect
ISideEffect personNameSideEffect = ISideEffect.create(() -> {
String name = showDescription.getValue() ? person.getFirstName() + " " + person.getLastName()
: person.getFirstName();
personNameText.setText(name);
});
// dispose the ISideEffect object on dispose
personNameText.addDisposeListener(e -> {
personNameSideEffect.dispose();
});
}
}
}