dhbw.clippinggorilla.userinterface.views.InterestProfileView.java Source code

Java tutorial

Introduction

Here is the source code for dhbw.clippinggorilla.userinterface.views.InterestProfileView.java

Source

/*
 * 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.views;

import com.vaadin.event.ShortcutAction;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.ExternalResource;
import com.vaadin.shared.ui.ContentMode;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.Accordion;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Image;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PopupView;
import com.vaadin.ui.TabSheet.Tab;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import dhbw.clippinggorilla.objects.category.Category;
import dhbw.clippinggorilla.objects.category.CategoryUtils;
import dhbw.clippinggorilla.objects.interestprofile.InterestProfile;
import dhbw.clippinggorilla.objects.interestprofile.InterestProfileUtils;
import dhbw.clippinggorilla.objects.source.Source;
import dhbw.clippinggorilla.objects.source.SourceUtils;
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.ui.VaadinUtils;
import elemental.events.KeyboardEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This is the class for the Interestprofile view
 *
 * @author Groove
 */
public class InterestProfileView extends VerticalLayout {

    private static final HashMap<User, InterestProfileView> SESSIONS = new HashMap<>();

    public static InterestProfileView getCurrent() {
        return new InterestProfileView();
    }

    private final Accordion accordion = new Accordion();

    public InterestProfileView() {
        User user = UserUtils.getCurrent();
        Set<InterestProfile> profiles = UserUtils.getAllInterestProfiles(user);

        CssLayout newProfileGroup = new CssLayout();
        newProfileGroup.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);

        TextField textFieldNewProfileName = new TextField();
        Language.setCustom(Word.PROFILE_NAME, s -> textFieldNewProfileName.setPlaceholder(s));
        textFieldNewProfileName.setWidth("260px");
        textFieldNewProfileName.setMaxLength(255);
        newProfileGroup.addComponent(textFieldNewProfileName);

        Button buttonNewProfile = new Button();
        buttonNewProfile.setIcon(VaadinIcons.PLUS);
        buttonNewProfile.addStyleName(ValoTheme.BUTTON_PRIMARY);
        buttonNewProfile.addClickListener(e -> {
            Tab newTab = accordion.addTab(createTab(createEmptyProfile(textFieldNewProfileName.getValue())),
                    textFieldNewProfileName.getValue());
            accordion.setSelectedTab(newTab);
            accordion.setWidth("100%");
            textFieldNewProfileName.clear();
        });
        newProfileGroup.addComponent(buttonNewProfile);
        textFieldNewProfileName
                .addFocusListener(f -> buttonNewProfile.setClickShortcut(ShortcutAction.KeyCode.ENTER, null));
        textFieldNewProfileName.addBlurListener(f -> buttonNewProfile.removeClickShortcut());

        profiles.forEach((InterestProfile profile) -> {
            accordion.addTab(createTab(profile), profile.getName());
        });
        addComponents(newProfileGroup, accordion);
        SESSIONS.put(user, this);
    }

    public VerticalLayout createTab(InterestProfile profile) {
        VerticalLayout profileSettingsLayout = new VerticalLayout();
        GridLayout tabContent = new GridLayout(3, 3);

        TextField textFieldName = new TextField();
        Language.set(Word.NAME, textFieldName);
        textFieldName.setWidth("100%");
        textFieldName.setValue(profile.getName());
        textFieldName.setMaxLength(255);
        CheckBox checkBoxEnabled = new CheckBox();
        checkBoxEnabled.setValue(profile.isEnabled());
        Language.setCustom(Word.ENABLED, s -> checkBoxEnabled.setCaption(s));

        Button buttonDelete = new Button();
        Language.set(Word.DELETE, buttonDelete);
        buttonDelete.setIcon(VaadinIcons.TRASH);
        buttonDelete.addStyleName(ValoTheme.BUTTON_DANGER);
        buttonDelete.addClickListener(ce -> {
            InterestProfileUtils.delete(profile);
            accordion.removeTab(accordion.getTab(profileSettingsLayout));
        });

        Button buttonSave = new Button();
        Language.set(Word.SAVE, buttonSave);
        buttonSave.setIcon(VaadinIcons.CHECK);
        buttonSave.addStyleName(ValoTheme.BUTTON_PRIMARY);
        buttonSave.addClickListener(ce -> {
            InterestProfileUtils.changeName(profile, textFieldName.getValue());
            accordion.getTab(profileSettingsLayout).setCaption(textFieldName.getValue());
            InterestProfileUtils.changeEnabled(profile, checkBoxEnabled.getValue());
            InterestProfileUtils.changeSources(profile, profile.getSources());
            InterestProfileUtils.changeCategories(profile, profile.getCategories());
            InterestProfileUtils.changeAllTags(profile, profile.getTags());
            VaadinUtils.infoNotification(Language.get(Word.SUCCESSFULLY_SAVED));
        });
        buttonSave.setClickShortcut(ShortcutAction.KeyCode.ENTER, null);

        Label placeholder = new Label();
        Label placeholder2 = new Label();
        placeholder2.setWidth("100%");

        Label labelHelp = new Label(Language.get(Word.HELP_TEXT), ContentMode.HTML);
        Language.setCustom(Word.HELP_TEXT, s -> labelHelp.setValue(s));
        labelHelp.setWidth("500px");
        PopupView popupHelp = new PopupView(null, labelHelp);

        Button buttonHelp = new Button(Language.get(Word.HELP), VaadinIcons.QUESTION);
        buttonHelp.addClickListener(ce -> {
            popupHelp.setPopupVisible(true);
        });

        GridLayout footer = new GridLayout(5, 1);
        footer.setSpacing(true);
        footer.setSizeUndefined();
        footer.addStyleName(ValoTheme.WINDOW_BOTTOM_TOOLBAR);
        footer.setWidth("100%");
        footer.addStyleName("menubar");
        footer.addComponents(buttonHelp, popupHelp, placeholder, buttonDelete, buttonSave);
        footer.setColumnExpandRatio(2, 5);
        footer.setComponentAlignment(buttonDelete, Alignment.MIDDLE_CENTER);
        footer.setComponentAlignment(buttonSave, Alignment.MIDDLE_CENTER);

        tabContent.addComponents(textFieldName, checkBoxEnabled, placeholder2);
        tabContent.addComponent(getSources(profile), 0, 1, 1, 1);
        tabContent.addComponent(getCategories(profile), 2, 1);
        tabContent.addComponent(getTags(profile), 0, 2, 2, 2);
        tabContent.setWidth("100%");
        tabContent.setSpacing(true);
        tabContent.setMargin(true);
        tabContent.addStyleName("profiles");
        tabContent.setComponentAlignment(textFieldName, Alignment.MIDDLE_LEFT);
        tabContent.setComponentAlignment(checkBoxEnabled, Alignment.MIDDLE_CENTER);
        profileSettingsLayout.addComponents(tabContent, footer);
        profileSettingsLayout.setMargin(false);
        profileSettingsLayout.setSpacing(false);
        profileSettingsLayout.setWidth("100%");
        return profileSettingsLayout;
    }

    public Component getSources(InterestProfile profile) {
        VerticalLayout windowLayout = new VerticalLayout();
        windowLayout.setWidth("100%");
        VerticalLayout sourcesLayout = new VerticalLayout();
        sourcesLayout.setWidth("100%");
        Panel sourcesPanel = new Panel(sourcesLayout);

        List<CheckBox> checkBoxes = new ArrayList<>();
        HashMap<String, GridLayout> sourceLayouts = new HashMap<>();
        profile.getSources().entrySet().stream()
                .sorted((e1, e2) -> e1.getKey().getName().compareToIgnoreCase(e2.getKey().getName())).forEach(e -> {
                    Source source = e.getKey();
                    boolean enabled = e.getValue();
                    GridLayout sourceLayout = new GridLayout(5, 1);
                    sourceLayout.setSizeFull();

                    CheckBox sourceSelected = new CheckBox();
                    sourceSelected.setValue(enabled);
                    sourceSelected.addStyleName(ValoTheme.CHECKBOX_LARGE);
                    sourceSelected.addValueChangeListener(v -> profile.getSources().replace(source, v.getValue()));
                    checkBoxes.add(sourceSelected);

                    Image sourceLogo = new Image();
                    sourceLogo.addStyleName("logosmall");
                    sourceLogo.setSource(new ExternalResource(source.getLogo()));
                    sourceLogo.addClickListener(c -> {
                        sourceSelected.setValue(!sourceSelected.getValue());
                        profile.getSources().replace(source, sourceSelected.getValue());
                    });
                    VerticalLayout layoutLogo = new VerticalLayout(sourceLogo);
                    layoutLogo.setWidth("150px");
                    layoutLogo.setHeight("50px");
                    layoutLogo.setMargin(false);
                    layoutLogo.setSpacing(false);
                    layoutLogo.setComponentAlignment(sourceLogo, Alignment.MIDDLE_LEFT);

                    Label labelHeadLine = new Label(
                            source.getCategory().getIcon().getHtml() + "  " + source.getName(), ContentMode.HTML);
                    labelHeadLine.addStyleName(ValoTheme.LABEL_H3);

                    Label labelDescription = new Label(source.getDescription(), ContentMode.HTML);
                    labelDescription.setWidth("300px");
                    PopupView popup = new PopupView(null, labelDescription);

                    Button buttonDescription = new Button(VaadinIcons.INFO_CIRCLE_O);
                    buttonDescription.addClickListener(ce -> {
                        popup.setPopupVisible(true);
                    });

                    sourceLayout.addComponents(sourceSelected, layoutLogo, labelHeadLine, popup, buttonDescription);
                    sourceLayout.setComponentAlignment(sourceSelected, Alignment.MIDDLE_CENTER);
                    sourceLayout.setComponentAlignment(layoutLogo, Alignment.MIDDLE_CENTER);
                    sourceLayout.setColumnExpandRatio(2, 5);
                    sourceLayout.setSpacing(true);

                    sourceLayouts.put(source.getName().toLowerCase().replaceAll(" ", "").replaceAll("-", "")
                            .replaceAll("_", ""), sourceLayout);
                    sourcesLayout.addComponent(sourceLayout);
                });

        sourcesPanel.setContent(sourcesLayout);
        sourcesPanel.setHeight("100%");
        sourcesPanel.setCaption(Language.get(Word.SOURCES));
        Language.setCustom(Word.SOURCES, s -> sourcesPanel.setCaption(s));
        windowLayout.addComponent(sourcesPanel);
        windowLayout.setExpandRatio(sourcesPanel, 1);
        windowLayout.setSpacing(false);
        windowLayout.setMargin(false);

        CheckBox checkBoxSelectAll = new CheckBox();
        Language.setCustom(Word.SELECT_ALL, s -> checkBoxSelectAll.setCaption(s));
        checkBoxSelectAll.setWidth("100%");
        checkBoxSelectAll.addValueChangeListener(e -> {
            profile.getSources().replaceAll((c, enabled) -> checkBoxSelectAll.getValue());
            checkBoxes.forEach(c -> c.setValue(checkBoxSelectAll.getValue()));
        });

        TextField textFieldSearch = new TextField();
        Language.setCustom(Word.SEARCH, s -> textFieldSearch.setPlaceholder(s));
        textFieldSearch.setWidth("100%");
        textFieldSearch.setMaxLength(255);
        textFieldSearch.setPlaceholder(Language.get(Word.SEARCH));
        textFieldSearch.addValueChangeListener(searchValue -> {
            sourceLayouts.forEach((sourceName, sourceLayout) -> {
                if (!sourceName.contains(searchValue.getValue().toLowerCase().replaceAll(" ", "")
                        .replaceAll("-", "").replaceAll("_", ""))) {
                    sourcesLayout.removeComponent(sourceLayout);
                } else {
                    sourcesLayout.addComponent(sourceLayout);
                }
            });
        });

        Label placeholder = new Label();
        placeholder.setWidth("100%");

        GridLayout footer = new GridLayout(3, 1);
        footer.setSpacing(true);
        footer.setMargin(new MarginInfo(true, false, false, false));
        footer.addStyleName("menubar");
        footer.setWidth("100%");
        footer.addComponents(checkBoxSelectAll, textFieldSearch, placeholder);
        footer.setComponentAlignment(checkBoxSelectAll, Alignment.MIDDLE_LEFT);
        footer.setComponentAlignment(textFieldSearch, Alignment.MIDDLE_CENTER);

        windowLayout.addComponent(footer);
        windowLayout.setHeight("350px");
        return windowLayout;
    }

    public Component getCategories(InterestProfile profile) {
        Map<Category, Boolean> categories = profile.getCategories();
        VerticalLayout categoriesLayout = new VerticalLayout();
        categoriesLayout.setWidth("100%");
        Panel categoriesPanel = new Panel(categoriesLayout);

        categories.entrySet().stream().sorted((e1, e2) -> e1.getKey().getName().compareTo(e2.getKey().getName()))
                .forEach(e -> {
                    Category category = e.getKey();
                    boolean enabled = e.getValue();
                    GridLayout categoryLayout = new GridLayout(3, 1);
                    categoryLayout.setWidth("100%");

                    CheckBox categorySelected = new CheckBox();
                    categorySelected.setValue(enabled);
                    categorySelected.addStyleName(ValoTheme.CHECKBOX_LARGE);
                    categorySelected.addValueChangeListener(v -> categories.replace(category, v.getValue()));

                    Label categoryIcon = new Label(category.getIcon().getHtml(), ContentMode.HTML);
                    categoryIcon.addStyleName(ValoTheme.LABEL_H3);
                    categoryIcon.addStyleName(ValoTheme.LABEL_NO_MARGIN);

                    Label categoryName = new Label(category.getName(), ContentMode.HTML);
                    Language.setCustom(null, s -> categoryName.setValue(category.getName()));
                    categoryName.addStyleName(ValoTheme.LABEL_H3);
                    categoryName.addStyleName(ValoTheme.LABEL_NO_MARGIN);

                    categoryLayout.addComponents(categorySelected, categoryIcon, categoryName);
                    categoryLayout.setComponentAlignment(categorySelected, Alignment.MIDDLE_CENTER);
                    categoryLayout.setComponentAlignment(categoryIcon, Alignment.MIDDLE_LEFT);
                    categoryLayout.setComponentAlignment(categoryName, Alignment.MIDDLE_LEFT);
                    categoryLayout.setColumnExpandRatio(2, 5);
                    categoryLayout.setSpacing(true);

                    categoriesLayout.addComponent(categoryLayout);
                });

        categoriesPanel.setContent(categoriesLayout);
        categoriesPanel.setHeight("100%");
        categoriesPanel.setCaption(Language.get(Word.CATEGORIES));
        Language.setCustom(Word.CATEGORIES, s -> categoriesPanel.setCaption(s));

        return categoriesPanel;
    }

    private static InterestProfile createEmptyProfile(String name) {
        Map<Source, Boolean> sources = new HashMap<>();
        Map<Category, Boolean> categories = new HashMap<>();
        Set<String> tags = new HashSet<>();

        SourceUtils.getSources().forEach(s -> sources.put(s, Boolean.FALSE));
        CategoryUtils.getCategories().forEach(c -> categories.put(c, Boolean.FALSE));
        return UserUtils.createNewProfile(UserUtils.getCurrent(), name, sources, tags, categories);
    }

    HashMap<InterestProfile, VerticalLayout> includedTagsLayouts = new HashMap<>();
    HashMap<InterestProfile, VerticalLayout> excludedTagsLayouts = new HashMap<>();

    public Component getTags(InterestProfile profile) {
        GridLayout allTagsLayout = new GridLayout(2, 1);
        Panel allTagsPanel = new Panel(allTagsLayout);
        allTagsPanel.setWidth("100%");
        allTagsPanel.setHeight("265px");
        allTagsPanel.setCaption(Language.get(Word.TAGS));
        Language.setCustom(Word.TAGS, s -> allTagsPanel.setCaption(s));

        VerticalLayout includedTagsLayout = new VerticalLayout();
        includedTagsLayouts.put(profile, includedTagsLayout);
        includedTagsLayout.setWidth("100%");
        includedTagsLayout.addStyleName("tags");
        Label labelIncludedTags = new Label(Language.get(Word.INCLUDE_TAGS));//Evtl only included
        Language.setCustom(Word.INCLUDE_TAGS, s -> labelIncludedTags.setValue(s));
        Component addIncludeTagGroup = getAddTagGroup(profile, true);
        includedTagsLayout.addComponents(labelIncludedTags, addIncludeTagGroup);
        includedTagsLayout.setComponentAlignment(labelIncludedTags, Alignment.MIDDLE_CENTER);
        includedTagsLayout.setComponentAlignment(addIncludeTagGroup, Alignment.MIDDLE_CENTER);

        VerticalLayout excludedTagsLayout = new VerticalLayout();
        excludedTagsLayouts.put(profile, excludedTagsLayout);
        excludedTagsLayout.setWidth("100%");
        excludedTagsLayout.addStyleName("tags");
        Label labelExcludedTags = new Label(Language.get(Word.EXCLUDE_TAGS));//Evtl only included
        Language.setCustom(Word.EXCLUDE_TAGS, s -> labelExcludedTags.setValue(s));
        Component addExcludeTagGroup = getAddTagGroup(profile, false);
        excludedTagsLayout.addComponents(labelExcludedTags, addExcludeTagGroup);
        excludedTagsLayout.setComponentAlignment(labelExcludedTags, Alignment.MIDDLE_CENTER);
        excludedTagsLayout.setComponentAlignment(addExcludeTagGroup, Alignment.MIDDLE_CENTER);

        profile.getTags().forEach((tag, included) -> addRow(profile, included, tag));

        allTagsLayout.addComponents(includedTagsLayout, excludedTagsLayout);
        allTagsLayout.setWidth("100%");
        return allTagsPanel;
    }

    private Component getAddTagGroup(InterestProfile profile, boolean included) {
        CssLayout newTagGroup = new CssLayout();
        newTagGroup.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);

        TextField textFieldTag = new TextField();
        textFieldTag.setWidth("325px");
        textFieldTag.setMaxLength(255);
        Language.setCustom(Word.NEW_TAG, s -> textFieldTag.setPlaceholder(s));

        Button buttonAddTag = new Button(VaadinIcons.PLUS);
        buttonAddTag.addStyleName(ValoTheme.BUTTON_PRIMARY);
        buttonAddTag.setClickShortcut(ShortcutAction.KeyCode.ENTER, null);
        buttonAddTag.addClickListener(event -> {
            addRow(profile, included, textFieldTag.getValue());
            profile.getTags().put(textFieldTag.getValue(), included);
            textFieldTag.clear();
        });
        textFieldTag.addFocusListener(f -> buttonAddTag.setClickShortcut(ShortcutAction.KeyCode.ENTER, null));
        textFieldTag.addBlurListener(f -> buttonAddTag.removeClickShortcut());

        newTagGroup.addComponents(textFieldTag, buttonAddTag);
        newTagGroup.setWidth("100%");
        return newTagGroup;
    }

    private void addRow(InterestProfile profile, boolean included, String value) {
        GridLayout tagLayout = new GridLayout(2, 1);
        tagLayout.setWidth("100%");

        Label labelTagName = new Label(value, ContentMode.HTML);
        labelTagName.setWidth("100%");
        labelTagName.addStyleName(ValoTheme.LABEL_H3);
        labelTagName.addStyleName(ValoTheme.LABEL_NO_MARGIN);

        Button buttonDeleteTag = new Button(VaadinIcons.TRASH);
        buttonDeleteTag.addStyleName(ValoTheme.BUTTON_DANGER);
        buttonDeleteTag.addClickListener(ev -> {
            profile.getTags().remove(value);
            if (included) {
                includedTagsLayouts.get(profile).removeComponent(tagLayout);
            } else {
                excludedTagsLayouts.get(profile).removeComponent(tagLayout);
            }
        });

        tagLayout.addComponents(labelTagName, buttonDeleteTag);
        tagLayout.setComponentAlignment(labelTagName, Alignment.MIDDLE_LEFT);
        tagLayout.setComponentAlignment(buttonDeleteTag, Alignment.MIDDLE_RIGHT);
        tagLayout.setWidth("100%");
        tagLayout.setColumnExpandRatio(0, 5);
        tagLayout.setSpacing(true);
        tagLayout.setMargin(false);

        if (included) {
            includedTagsLayouts.get(profile).addComponent(tagLayout, 2);
        } else {
            excludedTagsLayouts.get(profile).addComponent(tagLayout, 2);
        }
    }
}