de.decidr.ui.view.AbstractListComponent.java Source code

Java tutorial

Introduction

Here is the source code for de.decidr.ui.view.AbstractListComponent.java

Source

/*
 * The DecidR Development Team licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package de.decidr.ui.view;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickListener;

/**
 * Represents the general frame for every ListComponent, e.g.
 * a CustomComponent containing a search field above, buttons below,
 * and the actual list or table.
 *
 * @author Wolfgang Fellger
 */
public abstract class AbstractListComponent extends CustomComponent {

    /**
     * Policy for when to enable a button based on the current selection.
     * 
     * <ul>
     * <li>ALWAYS_AVAILABLE has the button always enabled.</li>
     * <li>ANY_SELECTED enables the button when at least one item is selected.</li>
     * <li>ONE_SELECTED enables the button when exactly one item is selected.</li>
     * </ul>
     */
    protected enum ButtonPolicy {
        ALWAYS_AVAILABLE, ANY_SELECTED, ONE_SELECTED
    }

    private static final long serialVersionUID = 4511228431124354018L;
    protected final VerticalLayout verticalLayout;
    protected final HorizontalLayout buttonHorizontalLayout;
    protected SearchPanel searchPanel = null;
    protected final Panel buttonPanel;
    protected Label label = null;
    protected Table contentTable = null;
    protected final List<Button> buttons;
    protected final Map<Button, ButtonPolicy> buttonPolicies;
    private ClickListener defaultAction;

    protected Component[] extraComponents = null;
    private final ValueChangeListener valueChangeListener;
    private final ItemClickListener itemClickListener;

    /**
     * TODO: add comment
     *
     */
    @SuppressWarnings("serial")
    public AbstractListComponent() {
        super();
        buttonPolicies = new HashMap<Button, ButtonPolicy>();
        buttons = new Vector<Button>();
        verticalLayout = new VerticalLayout();
        buttonHorizontalLayout = new HorizontalLayout();
        buttonPanel = new Panel();
        setCompositionRoot(verticalLayout);

        valueChangeListener = new Property.ValueChangeListener() {
            @Override
            public void valueChange(ValueChangeEvent event) {
                updateButtonStatus();

            }
        };
        itemClickListener = new ItemClickListener() {
            @Override
            public void itemClick(ItemClickEvent event) {
                System.out.println("Click!");
                if (event.isDoubleClick() && defaultAction != null) {
                    contentTable.setValue(event.getItemId());
                    defaultAction.buttonClick(null);
                }
            }
        };
    }

    /**
     * Create and add a button to the button panel.
     *
     * @param caption
     *          The button's caption
     * @param listener
     *          Action to be executed when button is clicked
     * @param policy
     *          Policy for when to activate the button; see {@link ButtonPolicy}
     * @param defaultButton
     *          <tt>true</tt> when this button's action should be called when
     *          the user double-clicks a list item.
     * @return
     *          The newly created button.
     */
    protected Button addButton(String caption, ClickListener listener, ButtonPolicy policy, boolean defaultButton) {
        Button button = new Button(caption, listener);
        buttonPolicies.put(button, policy);
        if (defaultButton) {
            this.defaultAction = listener;
        }
        buttonHorizontalLayout.addComponent(button);
        buttonPanel.requestRepaintAll();
        return button;
    }

    /**
     * Create and add a button to the button panel.<br>
     * This behaves like calling addButton with ButtonPolicy.ANY_SELECTED and
     * defaultButton = false.
     *
     * @param caption
     *          The button's caption
     * @param listener
     *          Action to be executed when button is clicked
     */
    protected void addButton(String caption, ClickListener listener) {
        addButton(caption, listener, ButtonPolicy.ANY_SELECTED, false);
    }

    /**
     * Remove all buttons and clear associated data.
     *
     */
    protected void removeAllButtons() {
        buttonPanel.removeAllComponents();
        buttonPolicies.clear();
        defaultAction = null;
    }

    /**
     * Replace contentTable with a new component. This will also update
     * dependant sub-components, e.g. the search panel.
     *
     * @param newContentTable
     */
    protected void replaceContentTable(Table newContentTable) {
        verticalLayout.replaceComponent(contentTable, newContentTable);
        contentTable = newContentTable;
        searchPanel.setTable(contentTable);
        contentTable.setImmediate(true);
        contentTable.addListener(valueChangeListener);
        contentTable.addListener(itemClickListener);
        updateButtonStatus();
    }

    /**
     * Returns the horizontal layout from the button panel.
     * 
     * @return buttonHorizontalLayout
     */
    public HorizontalLayout getButtonHorizontalLayout() {
        return buttonHorizontalLayout;
    }

    /**
     * Returns the button panel.
     * 
     * @return buttonPanel
     */
    public Panel getButtonPanel() {
        return buttonPanel;
    }

    /**
     * Returns the vertical layout.
     * 
     * @return verticalLayout
     */
    public VerticalLayout getVerticalLayout() {
        return verticalLayout;
    }

    /**
     * Run default initialization.<br>
     * Child classes should set up <tt>label, extraComponents</tt> and
     * <tt>contentTable</tt>
     * before calling this method.
     *
     */
    protected void init() {
        searchPanel = new SearchPanel(contentTable);
        verticalLayout.setSpacing(true);
        verticalLayout.addComponent(label);
        verticalLayout.addComponent(searchPanel);
        if (extraComponents != null) {
            for (Component comp : extraComponents) {
                verticalLayout.addComponent(comp);
            }
        }
        verticalLayout.addComponent(contentTable);
        buttonPanel.setContent(buttonHorizontalLayout);
        buttonHorizontalLayout.setSpacing(true);
        verticalLayout.addComponent(buttonPanel);

        contentTable.setImmediate(true);
        contentTable.addListener(valueChangeListener);
        contentTable.addListener(itemClickListener);
        updateButtonStatus();
    }

    protected void updateButtonStatus() {
        int numSelected = 0;
        Object value = contentTable.getValue();
        if (value != null) {
            if (value instanceof Set<?>) {
                numSelected = ((Set<?>) value).size();
            } else {
                numSelected = 1;
            }
        }
        for (Button button : buttonPolicies.keySet()) {
            if (buttonPolicies.get(button) == ButtonPolicy.ANY_SELECTED) {
                button.setEnabled(numSelected >= 1);
            } else if (buttonPolicies.get(button) == ButtonPolicy.ONE_SELECTED) {
                button.setEnabled(numSelected == 1);
            }
        }

    }
}