package pt.ist.vaadinframework.ui; import java.lang.reflect.Method; import pt.ist.vaadinframework.ui.factory.ResourceFactory; import com.vaadin.data.Item; import com.vaadin.data.Item.PropertySetChangeListener; import com.vaadin.data.Property; import com.vaadin.terminal.Resource; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Embedded; import com.vaadin.ui.GridLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; import com.vaadin.ui.themes.BaseTheme; /** * A DomainItem viewer that displays a domain item in a bar. * * @author David Martinho (davidmartinho@ist.utl.pt) * */ public abstract class ItemBarViewer extends CustomComponent implements Item.Viewer, Item.PropertySetChangeListener, Item.PropertySetChangeNotifier { private static final long serialVersionUID = -6263849010604509178L; private static final String AVATAR_SIZE = "30px"; private static final String CSS_ITEMBAR = "v-itembar"; private static final String CSS_ITEMBAR_WRAPPER = "v-itembar-wrapper"; private static final String CSS_ITEMBAR_AVATAR = "v-itembar-avatar"; private static final String CSS_ITEMBAR_NAME_LABEL = "v-itembar-name-label"; private static final String CSS_ITEMBAR_REMOVE_BUTTON = "v-itembar-remove-button"; private Panel container; private GridLayout itemBar; private Embedded avatar; private Label nameLabel; private Button removeButton; private Item itemDataSource; public ItemBarViewer() { bindUi(); } private void bindUi() { container = new Panel(); container.addStyleName(CSS_ITEMBAR); container.setSizeFull(); bindItemBar(); setCompositionRoot(container); } private void bindItemBar() { itemBar = new GridLayout(3, 1); itemBar.addStyleName(CSS_ITEMBAR_WRAPPER); container.setContent(itemBar); itemBar.setSizeFull(); bindAvatar(); bindNameLabel(); bindRemoveButton(); } private void bindAvatar() { avatar = new Embedded(); avatar.setWidth(AVATAR_SIZE); avatar.setHeight(AVATAR_SIZE); avatar.addStyleName(CSS_ITEMBAR_AVATAR); itemBar.addComponent(avatar, 0, 0, 0, 0); itemBar.setComponentAlignment(avatar, Alignment.MIDDLE_LEFT); } private void bindNameLabel() { nameLabel = new Label(); nameLabel.addStyleName(CSS_ITEMBAR_NAME_LABEL); itemBar.addComponent(nameLabel, 1, 0, 1, 0); itemBar.setComponentAlignment(nameLabel, Alignment.MIDDLE_LEFT); } private void bindRemoveButton() { removeButton = new Button("x"); removeButton.addStyleName(BaseTheme.BUTTON_LINK); removeButton.addStyleName(CSS_ITEMBAR_REMOVE_BUTTON); itemBar.addComponent(removeButton, 2, 0, 2, 0); itemBar.setComponentAlignment(removeButton, Alignment.MIDDLE_RIGHT); } public Button getRemoveButton() { return removeButton; } @Override public void setItemDataSource(Item newDataSource) { if (itemDataSource != null && Item.PropertySetChangeNotifier.class.isAssignableFrom(itemDataSource.getClass())) { ((Item.PropertySetChangeNotifier) itemDataSource).removeListener(this); } this.itemDataSource = newDataSource; refreshComponent(); if (itemDataSource != null && Item.PropertySetChangeNotifier.class.isAssignableFrom(itemDataSource.getClass())) { ((Item.PropertySetChangeNotifier) itemDataSource).addListener(this); } requestRepaint(); } private void refreshComponent() { avatar.setSource(getAvatarResource()); nameLabel.setPropertyDataSource(getNameProperty()); } public abstract Property getNameProperty(); /** * Override this method to control the avatar icon that is associated to the * item bar. * * @return the avatar resource to be included in the item bar */ protected Resource getAvatarResource() { return ResourceFactory.getAvatarFor(((Property) itemDataSource).getValue()); } @Override public Item getItemDataSource() { return itemDataSource; } @Override public void itemPropertySetChange(Item.PropertySetChangeEvent event) { fireItemPropertySetChangeEvent(); } private void fireItemPropertySetChangeEvent() { fireEvent(new ItemBarViewer.ItemPropertySetChangeEvent(this)); requestRepaint(); } @Override public void addListener(PropertySetChangeListener listener) { addListener(Item.PropertySetChangeListener.class, listener, ITEM_PROPERTY_SET_CHANGE_METHOD); } @Override public void removeListener(PropertySetChangeListener listener) { removeListener(Item.PropertySetChangeListener.class, listener, ITEM_PROPERTY_SET_CHANGE_METHOD); } public class ItemPropertySetChangeEvent extends Component.Event implements Item.PropertySetChangeEvent { private static final long serialVersionUID = -7389162648358822581L; public ItemPropertySetChangeEvent(ItemBarViewer itemBar) { super(itemBar); } @Override public Item getItem() { return (Item) getSource(); } } private static final Method ITEM_PROPERTY_SET_CHANGE_METHOD; static { try { ITEM_PROPERTY_SET_CHANGE_METHOD = Item.PropertySetChangeListener.class.getDeclaredMethod("itemPropertySetChange", new Class[] { Item.PropertySetChangeEvent.class }); } catch (final java.lang.NoSuchMethodException e) { throw new RuntimeException("Internal error finding methods in " + ItemBarViewer.class.getName()); } } }