Java tutorial
/* * 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); } } } }