fr.amapj.view.engine.listpart.StandardListPart.java Source code

Java tutorial

Introduction

Here is the source code for fr.amapj.view.engine.listpart.StandardListPart.java

Source

/*
 *  Copyright 2013-2018 Emmanuel BRUN (contact@amapj.fr)
 * 
 *  This file is part of AmapJ.
 *  
 *  AmapJ is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
    
 *  AmapJ is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with AmapJ.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * 
 */
package fr.amapj.view.engine.listpart;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import com.vaadin.data.Container.Filter;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.filter.Like;
import com.vaadin.data.util.filter.Or;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;

import fr.amapj.common.AmapjRuntimeException;
import fr.amapj.view.engine.popup.PopupListener;
import fr.amapj.view.engine.template.ListPartView;
import fr.amapj.view.engine.tools.TableItem;
import fr.amapj.view.engine.tools.TableTools;

/**
 * Ecran classique avec une liste d'elements 
 *
 */
@SuppressWarnings("serial")
abstract public class StandardListPart<T extends TableItem> extends ListPartView
        implements ComponentContainer, PopupListener {

    private TextField searchField;

    private List<ButtonHandler> buttons = new ArrayList<ButtonHandler>();

    private String textFilter;

    private BeanItemContainer<T> mcInfos;

    protected Table cdesTable;

    private Class<T> beanClazz;

    // Par defaut, une seule ligne est selectionnable  la fois 
    private boolean multiSelect;

    public StandardListPart(Class<T> beanClazz, boolean multiSelect) {
        this.beanClazz = beanClazz;
        this.multiSelect = multiSelect;
    }

    abstract protected String getTitle();

    abstract protected void drawButton();

    abstract protected void drawTable();

    /**
     * Composant entre le titre et la barre des boutons
     */
    protected void addSelectorComponent() {

    }

    /**
     * Composant entre la barre des boutons et la table
     */
    protected void addExtraComponent() {

    }

    /**
     * Retourne la liste des lignes  afficher 
     * 
     * Retourne null si l'ensemble des boutons doivent tre desactivs (par exemple,si le selector est dans un etat tel que 
     * l'ensemble des boutons doivent tre inactif)
     *  
     * @return
     */
    abstract protected List<T> getLines();

    abstract protected String[] getSortInfos();

    /**
     * Permet  la classe fille d'indiquer si le tri est ascendant ou descendant 
     * La taille du tableau retourne doit tre identique  la taille retourne par String[] getSortInfos()
     * 
     * Par dfaut, le tri est ascendant (true)
     * @return
     */
    protected boolean[] getSortAsc() {
        return null;
    }

    abstract protected String[] getSearchInfos();

    /**
     * Permet  l'implmentation fille d'indiquer si l'utilisateur a le droit d'diter cette ligne en particulier
     * Dans le cas gnaral, l'dition est autorise
     * @return
     */
    protected boolean isEditAllowed() {
        return true;
    }

    @Override
    public void enterIn(ViewChangeEvent event) {
        buildMainArea();
    }

    public void addButton(String label, ButtonType type, ListPartButtonListener listener) {
        Button newButton = new Button(label);
        newButton.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                listener.handleButtonPressed();
            }
        });

        //
        ButtonHandler handler = new ButtonHandler();
        handler.button = newButton;
        handler.type = type;
        buttons.add(handler);
    }

    public void addSearchField(String label) {
        searchField = new TextField();
        searchField.setInputPrompt(label);
        searchField.addTextChangeListener(new TextChangeListener() {

            @Override
            public void textChange(TextChangeEvent event) {
                textFilter = event.getText();
                updateFilters();
            }
        });
    }

    private void buildMainArea() {
        // Lecture dans la base de donnes
        mcInfos = new BeanItemContainer<T>(beanClazz);

        // Bind it to a component
        cdesTable = createTable(mcInfos);

        drawTable();

        cdesTable.setSelectable(true);
        cdesTable.setMultiSelect(multiSelect);
        cdesTable.setImmediate(true);

        // Activation ou desactivation des boutons delete et edit
        cdesTable.addValueChangeListener(new Property.ValueChangeListener() {
            @Override
            public void valueChange(ValueChangeEvent event) {
                if (multiSelect) {
                    Set s = (Set) event.getProperty().getValue();
                    buttonBarEditMode(s.size() > 0);
                } else {
                    buttonBarEditMode(event.getProperty().getValue() != null);
                }
            }
        });

        cdesTable.setSizeFull();

        cdesTable.addItemClickListener(new ItemClickListener() {
            @Override
            public void itemClick(ItemClickEvent event) {
                if (event.isDoubleClick()) {
                    cdesTable.select(event.getItemId());
                }
            }
        });

        HorizontalLayout toolbar = new HorizontalLayout();
        toolbar.addStyleName("buttonbar");

        Label title2 = new Label(getTitle());
        title2.setSizeUndefined();
        title2.addStyleName("title");

        drawButton();

        for (ButtonHandler handler : buttons) {
            toolbar.addComponent(handler.button);
        }

        if (searchField != null) {
            toolbar.addComponent(searchField);
            toolbar.setWidth("100%");
            toolbar.setExpandRatio(searchField, 1);
            toolbar.setComponentAlignment(searchField, Alignment.TOP_RIGHT);
        }

        addComponent(title2);
        addSelectorComponent();
        addComponent(toolbar);
        addExtraComponent();
        addComponent(cdesTable);
        setExpandRatio(cdesTable, 1);

        refreshTable();

    }

    private void updateFilters() {
        mcInfos.removeAllContainerFilters();
        if (textFilter != null && !textFilter.equals("")) {
            String[] searchInfos = getSearchInfos();
            Filter[] filters = new Filter[searchInfos.length];

            for (int i = 0; i < searchInfos.length; i++) {
                String search = searchInfos[i];
                filters[i] = new Like(search, "%" + textFilter + "%", false);
            }
            Or or = new Or(filters);
            mcInfos.addContainerFilter(or);
        }
    }

    /**
     * Permet de rafraichir la table
     */
    public void refreshTable() {
        String[] sortColumns = getSortInfos();
        boolean[] ascColumns = getSortAsc();
        boolean[] sortAscending;
        if (ascColumns == null) {
            sortAscending = new boolean[sortColumns.length];
            Arrays.fill(sortAscending, true);
        } else {
            if (ascColumns.length != sortColumns.length) {
                throw new AmapjRuntimeException(
                        "Les deux mthodes getSortAsc et getSortInfos doivent retourner deux tableaux de mme taille");
            }
            sortAscending = ascColumns;
        }

        List<T> res = getLines();

        if (res == null) {
            mcInfos.removeAllItems();
            buttonBarFull(false);
            return;
        }

        boolean enabled;

        if (multiSelect == true) {
            enabled = TableTools.updateTableMultiselect(cdesTable, res, sortColumns, sortAscending);
        } else {
            enabled = TableTools.updateTable(cdesTable, res, sortColumns, sortAscending);
        }

        buttonBarFull(true);
        buttonBarEditMode(enabled);
    }

    @Override
    public void onPopupClose() {
        refreshTable();

    }

    /**
     * Permet d'activer ou de dsactiver toute la barre des boutons
     * 
     */
    private void buttonBarFull(boolean enable) {
        for (ButtonHandler handler : buttons) {
            handler.button.setEnabled(enable);
        }
    }

    /**
     * Permet d'activer ou de dsactiver les boutons de la barre 
     * qui sont relatifs au mode dition, c'est  dire les boutons 
     * Edit et Delete
     */
    private void buttonBarEditMode(boolean enable) {
        if ((enable == true) && isEditAllowed() == false) {
            enable = false;
        }

        for (ButtonHandler handler : buttons) {
            if (handler.type == ButtonType.EDIT_MODE) {
                handler.button.setEnabled(enable);
            }
        }
    }

    /**
     * Retourne la liste des lignes selectionnes
     * @return
     */
    protected List<T> getSelectedLines() {
        if (multiSelect == false) {
            throw new AmapjRuntimeException("Vous ne pouvez pas utiliser cette methode en mono selection ");
        }

        List<T> res = new ArrayList<T>();
        Set s = (Set) cdesTable.getValue();
        res.addAll(s);
        return res;
    }

    /**
     * Retourne la ligne selectionne
     * 
     * Peux retourner null si il n'y a pas de ligne selectionne
     * @return
     */
    protected T getSelectedLine() {
        if (multiSelect == true) {
            throw new AmapjRuntimeException("Vous ne pouvez pas utiliser cette methode en multi selection ");
        }

        T dto = (T) cdesTable.getValue();
        return dto;
    }

    public BeanItemContainer<T> getBeanItemContainer() {
        return mcInfos;
    }

}