Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package dhbw.clippinggorilla.userinterface.windows; import com.vaadin.event.ShortcutAction; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.icons.VaadinIcons; import com.vaadin.server.AbstractErrorMessage; import com.vaadin.server.ErrorMessage; import com.vaadin.server.Page; import com.vaadin.server.UserError; import com.vaadin.server.VaadinSession; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.shared.ui.datefield.DateTimeResolution; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Component; import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.InlineDateTimeField; import com.vaadin.ui.Label; import com.vaadin.ui.PasswordField; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.TabSheet; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; import dhbw.clippinggorilla.external.mailserver.Mail; import dhbw.clippinggorilla.objects.user.User; import dhbw.clippinggorilla.objects.user.UserUtils; import dhbw.clippinggorilla.utilities.language.Language; import dhbw.clippinggorilla.utilities.language.Word; import dhbw.clippinggorilla.utilities.log.Log; import dhbw.clippinggorilla.utilities.ressources.Props; import dhbw.clippinggorilla.utilities.ui.VaadinUtils; import java.time.Clock; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.mail.EmailAttachment; import org.apache.commons.mail.EmailException; /** * This is the preferences window * * @author frank */ public class PreferencesWindow extends Window { public static Window get(User user) { return new PreferencesWindow(user); } public PreferencesWindow(User user) { //setHeight("480px"); //setWidth("720px"); VerticalLayout windowContent = new VerticalLayout(); windowContent.setWidth("100%"); windowContent.setHeight("100%"); windowContent.setMargin(new MarginInfo(true, false, false, false)); TabSheet preferencesCategories = new TabSheet(); preferencesCategories.setWidth("100%"); preferencesCategories.setHeight("100%"); preferencesCategories.addStyleName(ValoTheme.TABSHEET_PADDED_TABBAR); preferencesCategories.addStyleName(ValoTheme.TABSHEET_ICONS_ON_TOP); preferencesCategories.addStyleName(ValoTheme.TABSHEET_CENTERED_TABS); windowContent.addComponent(preferencesCategories); windowContent.setExpandRatio(preferencesCategories, 1f); preferencesCategories.addComponent(buildUserTab(user)); preferencesCategories.addComponent(buildClippingsTab(user)); preferencesCategories.addComponent(buildSupportTab(user)); preferencesCategories.setSelectedTab(0); windowContent.addComponent(buildFooter(user)); setContent(windowContent); setModal(true); addCloseShortcut(KeyCode.ENTER, null); setResizable(false); setClosable(false); setHeight("480px"); setWidth("720px"); } TextField firstNameField; TextField lastNameField; TextField usernameField; TextField emailField; PasswordField oldPasswordField; PasswordField password1Field; PasswordField password2Field; private Component buildUserTab(User user) { HorizontalLayout root = new HorizontalLayout(); root.setCaption(Language.get(Word.PROFILE)); root.setIcon(VaadinIcons.USER); root.setWidth("100%"); root.setSpacing(true); root.setMargin(true); FormLayout details = new FormLayout(); details.addStyleName(ValoTheme.FORMLAYOUT_LIGHT); root.addComponent(details); firstNameField = new TextField(Language.get(Word.FIRST_NAME)); firstNameField.setValue(user.getFirstName()); firstNameField.setMaxLength(20); firstNameField.addValueChangeListener(event -> { String firstNameError = UserUtils.checkName(event.getValue()); if (!firstNameError.isEmpty()) { firstNameField.setComponentError(new UserError(firstNameError, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(firstNameError); saveButton.setEnabled(setError(firstNameField, true)); } else { firstNameField.setComponentError(null); boolean enabled = setError(firstNameField, false); saveButton.setEnabled(enabled); } }); setError(firstNameField, false); lastNameField = new TextField(Language.get(Word.LAST_NAME)); lastNameField.setValue(user.getLastName()); lastNameField.setMaxLength(20); lastNameField.addValueChangeListener(event -> { String lastNameError = UserUtils.checkName(event.getValue()); if (!lastNameError.isEmpty()) { lastNameField.setComponentError(new UserError(lastNameError, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(lastNameError); saveButton.setEnabled(setError(lastNameField, true)); } else { lastNameField.setComponentError(null); saveButton.setEnabled(setError(lastNameField, false)); } }); setError(lastNameField, false); usernameField = new TextField(Language.get(Word.USERNAME)); usernameField.setValue(user.getUsername()); usernameField.setMaxLength(20); usernameField.addValueChangeListener(event -> { if (!event.getValue().equals(user.getUsername())) { String userNameError = UserUtils.checkUsername(event.getValue()); if (!userNameError.isEmpty()) { usernameField.setComponentError(new UserError(userNameError, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(userNameError); saveButton.setEnabled(setError(usernameField, true)); } else { usernameField.setComponentError(null); saveButton.setEnabled(setError(usernameField, false)); } } else { usernameField.setComponentError(null); saveButton.setEnabled(setError(usernameField, false)); } }); setError(usernameField, false); emailField = new TextField(Language.get(Word.EMAIL)); emailField.setValue(user.getEmail()); emailField.setMaxLength(256); emailField.addValueChangeListener(event -> { if (!event.getValue().equals(user.getEmail())) { String email1Error = UserUtils.checkEmail(event.getValue().toLowerCase()); if (!email1Error.isEmpty()) { emailField.setComponentError(new UserError(email1Error, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(email1Error); saveButton.setEnabled(setError(emailField, true)); } else { emailField.setComponentError(null); saveButton.setEnabled(setError(emailField, false)); } } else { emailField.setComponentError(null); saveButton.setEnabled(setError(emailField, false)); } }); setError(emailField, false); oldPasswordField = new PasswordField(Language.get(Word.OLD_PASSWORD)); oldPasswordField.setValue(""); oldPasswordField.setMaxLength(51); oldPasswordField.addValueChangeListener(event -> { if (!event.getValue().isEmpty()) { String password1Error = UserUtils.checkPassword(event.getValue()); if (!password1Error.isEmpty()) { oldPasswordField.setComponentError(new UserError(password1Error, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(password1Error); saveButton.setEnabled(setError(oldPasswordField, true)); } else { oldPasswordField.setComponentError(null); saveButton.setEnabled(setError(oldPasswordField, false)); } } else { oldPasswordField.setComponentError(null); saveButton.setEnabled(setError(oldPasswordField, false)); } }); setError(oldPasswordField, false); ProgressBar strength = new ProgressBar(); password1Field = new PasswordField(Language.get(Word.PASSWORD)); password1Field.setValue(""); password1Field.setMaxLength(51); password1Field.addValueChangeListener(event -> { if (!event.getValue().isEmpty()) { String password1Error = UserUtils.checkPassword(event.getValue()); strength.setValue(UserUtils.calculatePasswordStrength(event.getValue())); if (!password1Error.isEmpty()) { password1Field.setComponentError(new UserError(password1Error, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(password1Error); saveButton.setEnabled(setError(password1Field, true)); } else { password1Field.setComponentError(null); saveButton.setEnabled(setError(password1Field, false)); } } else { password1Field.setComponentError(null); saveButton.setEnabled(setError(password1Field, false)); } }); setError(password1Field, false); strength.setWidth("184px"); strength.setHeight("1px"); password2Field = new PasswordField(Language.get(Word.PASSWORD_AGAIN)); password2Field.setValue(""); password2Field.setMaxLength(51); password2Field.addValueChangeListener(event -> { if (!event.getValue().isEmpty()) { String password2Error = UserUtils.checkPassword(event.getValue()) + UserUtils.checkSecondPassword(password1Field.getValue(), event.getValue()); if (!password2Error.isEmpty()) { password2Field.setComponentError(new UserError(password2Error, AbstractErrorMessage.ContentMode.HTML, ErrorMessage.ErrorLevel.INFORMATION)); VaadinUtils.infoNotification(password2Error); saveButton.setEnabled(setError(password2Field, true)); } else { password2Field.setComponentError(null); saveButton.setEnabled(setError(password2Field, false)); } } else { password2Field.setComponentError(null); saveButton.setEnabled(setError(password2Field, false)); } }); setError(password2Field, false); details.addComponents(firstNameField, lastNameField, usernameField, emailField, oldPasswordField, password1Field, strength, password2Field); return root; } private VerticalLayout layoutClippingTimes; // private final int offsetInSec = Page.getCurrent().getWebBrowser().getTimezoneOffset() / 1000; // private final ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetInSec); private Component buildClippingsTab(User user) { HorizontalLayout root = new HorizontalLayout(); root.setCaption(Language.get(Word.CLIPPINGS)); root.setIcon(VaadinIcons.NEWSPAPER); root.setWidth("100%"); root.setSpacing(true); root.setMargin(true); FormLayout formLayoutClippingDetails = new FormLayout(); formLayoutClippingDetails.addStyleName(ValoTheme.FORMLAYOUT_LIGHT); root.addComponent(formLayoutClippingDetails); CheckBox checkBoxReceiveEmails = new CheckBox(); checkBoxReceiveEmails.setValue(UserUtils.getEmailNewsletter(user)); checkBoxReceiveEmails.addValueChangeListener(v -> UserUtils.setEmailNewsletter(user, v.getValue())); HorizontalLayout layoutCheckBoxReceiveEmails = new HorizontalLayout(checkBoxReceiveEmails); layoutCheckBoxReceiveEmails.setCaption(Language.get(Word.EMAIL_SUBSCRIPTION)); layoutCheckBoxReceiveEmails.setMargin(false); layoutCheckBoxReceiveEmails.setSpacing(false); HorizontalLayout layoutAddNewClippingTime = new HorizontalLayout(); layoutAddNewClippingTime.setMargin(false); layoutAddNewClippingTime.setCaption(Language.get(Word.ADD_CLIPPING_TIME)); layoutAddNewClippingTime.setWidth("100%"); InlineDateTimeField dateFieldNewClippingTime = new InlineDateTimeField(); LocalDateTime value = LocalDateTime.now(ZoneId.of("Europe/Berlin")); dateFieldNewClippingTime.setValue(value); dateFieldNewClippingTime.setLocale(VaadinSession.getCurrent().getLocale()); dateFieldNewClippingTime.setResolution(DateTimeResolution.MINUTE); dateFieldNewClippingTime.addStyleName("time-only"); Button buttonAddClippingTime = new Button(); buttonAddClippingTime.setIcon(VaadinIcons.PLUS); buttonAddClippingTime.addStyleName(ValoTheme.BUTTON_PRIMARY); buttonAddClippingTime.setClickShortcut(ShortcutAction.KeyCode.ENTER, null); buttonAddClippingTime.addClickListener(e -> { LocalTime generalTime = dateFieldNewClippingTime.getValue().toLocalTime(); layoutClippingTimes.addComponent(getTimeRow(user, generalTime)); UserUtils.addClippingSendTime(user, generalTime); }); layoutAddNewClippingTime.addComponents(dateFieldNewClippingTime, buttonAddClippingTime); layoutAddNewClippingTime.setComponentAlignment(dateFieldNewClippingTime, Alignment.MIDDLE_LEFT); layoutAddNewClippingTime.setComponentAlignment(buttonAddClippingTime, Alignment.MIDDLE_CENTER); layoutAddNewClippingTime.setExpandRatio(dateFieldNewClippingTime, 5); layoutClippingTimes = new VerticalLayout(); layoutClippingTimes.setMargin(new MarginInfo(true, false, false, true)); layoutClippingTimes.setCaption(Language.get(Word.CLIPPING_TIMES)); layoutClippingTimes.setWidth("100%"); layoutClippingTimes.addStyleName("times"); Set<LocalTime> userTimes = user.getClippingTime(); userTimes.forEach(t -> layoutClippingTimes.addComponent(getTimeRow(user, t))); formLayoutClippingDetails.addComponents(layoutCheckBoxReceiveEmails, layoutAddNewClippingTime, layoutClippingTimes); return root; } private Component getTimeRow(User user, LocalTime time) { HorizontalLayout layoutTimeRow = new HorizontalLayout(); layoutTimeRow.setWidth("100%"); DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT); Label labelTime = new Label(time.format(formatter)); Button buttonDelete = new Button(VaadinIcons.TRASH); buttonDelete.addStyleName(ValoTheme.BUTTON_DANGER); buttonDelete.setWidth("80px"); buttonDelete.addClickListener(e -> { if (layoutClippingTimes.getComponentCount() > 1) { layoutClippingTimes.removeComponent(layoutTimeRow); UserUtils.removeClippingSendTime(user, time); } else { VaadinUtils.errorNotification(Language.get(Word.AT_LREAST_ONE_TIME)); } }); layoutTimeRow.addComponents(labelTime, buttonDelete); layoutTimeRow.setComponentAlignment(labelTime, Alignment.MIDDLE_LEFT); layoutTimeRow.setComponentAlignment(buttonDelete, Alignment.MIDDLE_CENTER); layoutTimeRow.setExpandRatio(labelTime, 5); return layoutTimeRow; } private Button saveButton = new Button(); private Component buildFooter(User user) { HorizontalLayout footer = new HorizontalLayout(); footer.addStyleName(ValoTheme.WINDOW_BOTTOM_TOOLBAR); footer.setWidth(100.0f, Unit.PERCENTAGE); Button cancelButton = new Button(Language.get(Word.CANCEL)); cancelButton.setIcon(VaadinIcons.CLOSE); cancelButton.addClickListener(event -> { close(); }); saveButton = new Button(Language.get(Word.SAVE)); saveButton.setIcon(VaadinIcons.CHECK); saveButton.addStyleName(ValoTheme.BUTTON_PRIMARY); saveButton.addClickListener(event -> { boolean error = false; if (!user.getFirstName().equals(firstNameField.getValue())) { boolean success = UserUtils.changeFirstName(user, firstNameField.getValue()); if (!success) { error = true; } } if (!user.getLastName().equals(lastNameField.getValue())) { boolean success = UserUtils.changeLastName(user, lastNameField.getValue()); if (!success) { error = true; } } if (!user.getUsername().equals(usernameField.getValue())) { boolean success = UserUtils.changeUsername(user, usernameField.getValue()); if (!success) { error = true; } } if (!user.getEmail().equals(emailField.getValue())) { UI.getCurrent().addWindow(ActivateWindow.get()); boolean success = UserUtils.changeEmail(user, user.getEmail(), emailField.getValue(), emailField.getValue()); if (!success) { error = true; } } boolean wrongPW = false; if (!password1Field.isEmpty() && password1Field.getValue().equals(password2Field.getValue())) { wrongPW = !UserUtils.changePassword(user, oldPasswordField.getValue(), password1Field.getValue(), password2Field.getValue()); } if (error) { VaadinUtils.errorNotification(Language.get(Word.UNEXPECTED_ERROR)); } else if (wrongPW) { VaadinUtils.errorNotification(Language.get(Word.WRONG_PASSWORD)); } else { VaadinUtils.infoNotification(Language.get(Word.SUCCESSFULLY_SAVED)); close(); } }); saveButton.focus(); Label placeholder = new Label(); footer.addComponents(placeholder, cancelButton, saveButton); footer.setExpandRatio(placeholder, 5); footer.setComponentAlignment(cancelButton, Alignment.TOP_CENTER); footer.setComponentAlignment(saveButton, Alignment.TOP_CENTER); return footer; } private final HashMap<Component, Boolean> errors = new HashMap<>(); public boolean setError(Component toBeChecked, boolean error) { errors.put(toBeChecked, error); return errors.size() == 7 && errors.values().stream().allMatch(v -> v == false); } static HashMap<User, Map<LocalDate, Integer>> emailsSend = new HashMap<>(); private Component buildSupportTab(User user) { VerticalLayout root = new VerticalLayout(); root.setCaption(Language.get(Word.SUPPORT)); root.setIcon(VaadinIcons.HEADSET); root.setWidth("100%"); root.setHeight("100%"); root.setSpacing(true); root.setMargin(true); TextArea textAreaMessage = new TextArea(Language.get(Word.MESSAGE)); textAreaMessage.setWidth("100%"); textAreaMessage.setHeight("100%"); Button buttonSend = new Button(Language.get(Word.SEND), VaadinIcons.ENVELOPE); buttonSend.addStyleName(ValoTheme.BUTTON_PRIMARY); buttonSend.addClickListener(ce -> { try { if (emailsSend.containsKey(user)) { Map<LocalDate, Integer> times = emailsSend.get(user); if (times.containsKey(LocalDate.now())) { if (times.get(LocalDate.now()) > 3) { if (times.get(LocalDate.now()) > 15) { UserUtils.banUser(user); VaadinUtils.errorNotification("BANNED DUE TO TOO MUCH EMAILS"); } else { VaadinUtils.errorNotification("TOO MUCH EMAILS"); } return; } else { times.put(LocalDate.now(), times.get(LocalDate.now()) + 1); } } else { times.put(LocalDate.now(), 1); } } else { HashMap<LocalDate, Integer> times = new HashMap<>(); times.put(LocalDate.now(), 1); emailsSend.put(user, times); } Mail.send(Props.get("supportmail"), "SUPPORT", user.toString() + "\n" + textAreaMessage.getValue()); VaadinUtils.middleInfoNotification(Language.get(Word.SUCCESSFULLY_SEND)); textAreaMessage.clear(); } catch (EmailException ex) { VaadinUtils.errorNotification(Language.get(Word.SEND_FAILED)); Log.error("Could not send Supportmail: ", ex); } }); root.addComponents(textAreaMessage, buttonSend); root.setExpandRatio(textAreaMessage, 5); root.setComponentAlignment(buttonSend, Alignment.MIDDLE_LEFT); return root; } }