Git Product home page Git Product logo

annomvvm's Introduction

annoMVVM Build Status

Simple MVVM framework for Java applications

##Configuring annoMVVM for Vaadin ###StateChangeListener In order for the ViewModelComposer to know how to synchronise a viewmodel's changed State with the bound field in the view, a StateChangeListener has to be provided. There can be different listeners for different types of fields, in the following an example for providing a listener for Vaadin's AbstractField and for a State of this framework:

  viewModelComposer.addStateChangeWrapper(AbstractField.class,
  		new StateChangeWrapper() {
  			@Override
  			public StateChangeListener getStateChangeListener(
  					final Object notified) {
  				return new StateChangeListener() {
  					@SuppressWarnings("unchecked")
  					@Override
  					public void stateChange(Object value) {
  						//synchronise the state by invoking AbstractField.setValue
  						((AbstractField<Object>) notified)
  								.setValue(value);
  					}
  				};
  			}
  		});
  
  viewModelComposer.addStateChangeWrapper(State.class,
  		new StateChangeWrapper() {
  			@Override
  			public StateChangeListener getStateChangeListener(
  					final Object notified) {
  				return new StateChangeListener() {
  					@SuppressWarnings("unchecked")
  					@Override
  					public void stateChange(Object value) {
  						//synchronise the state by invoking State.set
  						((State<Object>) notified).set(value);
  					}
  				};
  			}
  		});

###SourceWrapper When defining source fields in the @BindAction annotation, a SourceWrapper for the type of a source field has to be provided. It specifies how the data should be extracted from the source field.

  viewModelComposer.addSourceWrapper(AbstractField.class,
  		new SourceWrapper<Object>() {
  			@SuppressWarnings("unchecked")
  			@Override
  			public Object get(Object source) {
  				return ((AbstractField<Object>) source).getValue();
  			}
  		});

###ActionHandler When no source fields are defined in the @BindAction annotation, an ActionHandler has to be provided, which specifies what data should be passed on to the invoked method in the viewmodel.

  viewModelComposer.addActionWrapper(ValueChangeNotifier.class,
  		new ActionWrapper() {
  			@Override
  			public void addActionHandler(Object notifier,
  					final ActionHandler actionHandler) {
  				((ValueChangeNotifier) notifier)
  						.addValueChangeListener(new ValueChangeListener() {
  							private static final long serialVersionUID = -854400079672018869L;
  
  							@Override
  							public void valueChange(
  									ValueChangeEvent event) {
  								actionHandler.handle(event.getProperty().getValue());
  							}
  						});
  			}
  		});
  
  viewModelComposer.addActionWrapper(Button.class, new ActionWrapper() {
  	@Override
  	public void addActionHandler(Object notifier,
  			final ActionHandler actionHandler) {
  		((Button) notifier).addClickListener(new ClickListener() {
  			private static final long serialVersionUID = 3154305342571215268L;
  
  			@Override
  			public void buttonClick(ClickEvent event) {
  				actionHandler.handle(event.getButton().getData());
  			}
  		});
  	}
  });

##Usage of the annotations Annotations can be used for either passing events in the view to the viewmodel or synchronising a state in the viewmodel with the counterpart in the view.

###@BindAction For binding an action in a view to a method in a viewmodel, an ActionHandler needs to be declared in the viewmodel:

public interface DoLogout extends ActionHandler {}

The declared handler can then be used in a @HandlesAction annotation on a method in the viewmodel:

@HandlesAction(DoLogin.class)
public void doLogin(String username, String password) {
	//do something with username and password
}

Now the method can be bound in the view:

private TextField user = new TextField("User:");
private PasswordField password = new PasswordField("Password:");

@BindAction(value = DoLogin.class, source = { "user", "password" })
private Button loginButton;

Make sure the fields in the view are initialised properly - otherwise you might get a NullPointerException when binding the view to the viewmodel.

###@BindState For binding a state in a viewmodel to a synchronised field in a view, a State needs to be declared in the viewmodel:

public interface IsLoggedIn extends State<Boolean> {}
public interface UserInformation extends State<String> {}

The declared state can then be used in a @ProvidesState annotation on a State field in the viewmodel:

@ProvidesState(IsLoggedIn.class)
public final BasicState<Boolean> isLoggedIn = new BasicState<Boolean>(Boolean.class);

@ProvidesState(UserInformation.class)
public final BasicState<String> userInformation = new BasicState<String>(String.class);

Now a field in the view can be synchronised with the State:

@BindState(IsLoggedIn.class)
private BasicState<Boolean> isLoggedIn = new BasicState<Boolean>(Boolean.class);

@BindState(UserInformation.class)
private Label labelUserInformation = new Label();

When a State is changed in the viewmodel, it now automatically synchronises with the bound fields in the views:

isLoggedIn.set(false);
userInformation.set("User: abc");

Author: David Herrmann, 2013

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.