package de.dhbw.humbuch.view; import java.util.NoSuchElementException; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.inject.Inject; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.event.ShortcutListener; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.CssLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.PasswordField; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import de.davherrmann.mvvm.BasicState; import de.davherrmann.mvvm.StateChangeListener; import de.davherrmann.mvvm.ViewModelComposer; import de.davherrmann.mvvm.annotations.BindAction; import de.davherrmann.mvvm.annotations.BindState; import de.dhbw.humbuch.event.LoginEvent; import de.dhbw.humbuch.viewmodel.LoginViewModel; import de.dhbw.humbuch.viewmodel.LoginViewModel.DoLogin; import de.dhbw.humbuch.viewmodel.LoginViewModel.IsLoggedIn; /** * Provides the UI for the login and displays error messages, if the user uses * wrong credentials * * @author Johannes Idelhauser */ public class LoginView extends VerticalLayout implements View { private static final long serialVersionUID = 5187769743375079627L; private VerticalLayout loginLayout; private CssLayout loginPanel; private TextField username = new TextField("Username"); private PasswordField password = new PasswordField("Passwort"); @BindAction(value = DoLogin.class, source = { "username", "password" }) private Button btnLogin = new Button("Login"); @BindState(IsLoggedIn.class) private BasicState<Boolean> isLoggedIn = new BasicState<Boolean>(Boolean.class); @Inject public LoginView(ViewModelComposer viewModelComposer, LoginViewModel loginViewModel, EventBus eventBus) { eventBus.register(this); init(); buildLayout(); bindViewModel(viewModelComposer, loginViewModel); } /** * Initializes the components and sets attributes. */ private void init() { loginLayout = new VerticalLayout(); loginLayout.setSizeFull(); loginLayout.addStyleName("login-layout"); loginPanel = new CssLayout(); loginPanel.addStyleName("login-panel"); // Labels HorizontalLayout labels = new HorizontalLayout(); labels.setWidth("100%"); labels.setMargin(true); labels.addStyleName("labels"); loginPanel.addComponent(labels); // Welcome Label welcome = new Label("Herzlich Willkommen"); welcome.setSizeUndefined(); welcome.addStyleName("h4"); labels.addComponent(welcome); labels.setComponentAlignment(welcome, Alignment.MIDDLE_LEFT); // HumBuch Label title = new Label("HumBuch<br />Schulbuchverwaltung", ContentMode.HTML); title.setSizeUndefined(); title.addStyleName("h2"); labels.addComponent(title); labels.setComponentAlignment(title, Alignment.MIDDLE_RIGHT); // Input fields HorizontalLayout fields = new HorizontalLayout(); fields.setSpacing(true); fields.setMargin(true); fields.addStyleName("fields"); // Username username.setNullRepresentation(""); fields.addComponent(username); // Password password.setNullRepresentation(""); fields.addComponent(password); // Button btnLogin.addStyleName("default"); fields.addComponent(btnLogin); fields.setComponentAlignment(btnLogin, Alignment.BOTTOM_LEFT); loginPanel.addComponent(fields); loginLayout.addComponent(loginPanel); loginLayout.setComponentAlignment(loginPanel, Alignment.MIDDLE_CENTER); attachListeners(); } /** * Adds all listener to their corresponding components */ private void attachListeners() { /** * Checks for a successful login and navigates to home_view */ isLoggedIn.addStateChangeListener(new StateChangeListener() { @Override public void stateChange(Object arg0) { if (isLoggedIn.get()) { // Navigate to main view if (getUI() != null && getUI().getNavigator() != null) { getUI().getNavigator().navigateTo(MainUI.LENDING_VIEW); } } } }); /** * Listens for key press <enter> */ final ShortcutListener enter = new ShortcutListener("Sign In", KeyCode.ENTER, null) { private static final long serialVersionUID = 2980349254427801100L; @Override public void handleAction(Object sender, Object target) { btnLogin.click(); } }; username.addShortcutListener(enter); password.addShortcutListener(enter); } /** * Builds the layout by adding the components to the view */ private void buildLayout() { setSizeFull(); addComponent(loginLayout); } /** * Handles {@link LoginEvent}s posted via the {@link EventBus} * * @param loginEvent * a {@link LoginEvent} */ @Subscribe public void handleLoginEvent(LoginEvent loginEvent) { if (loginPanel.getComponentCount() > 2) { // Remove the previous error message loginPanel.removeComponent(loginPanel.getComponent(2)); } Label error = new Label(loginEvent.getMessage(), ContentMode.HTML); error.setStyleName("error"); error.setSizeUndefined(); // add animation error.addStyleName("v-animate-reveal"); loginPanel.addComponent(error); username.focus(); } private void bindViewModel(ViewModelComposer viewModelComposer, Object... viewModels) { try { viewModelComposer.bind(this, viewModels); } catch (IllegalAccessException | NoSuchElementException | UnsupportedOperationException e) { e.printStackTrace(); } } /** * {@inheritDoc} */ @Override public void enter(ViewChangeEvent event) { if (loginPanel.getComponentCount() > 2) { // Remove the previous error message loginPanel.removeComponent(loginPanel.getComponent(2)); } username.setValue(""); password.setValue(""); username.focus(); } }