package fr.lteconsulting.hexa.databinding.gwt.propertyadapters; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.ListBox; import fr.lteconsulting.hexa.client.tools.Action2; import fr.lteconsulting.hexa.databinding.propertyadapters.PropertyAdapter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Logger; /** * A PropertyAdapter to bind a {@link ListBox}.<br/> * * - When receiving an object, the adapter will set it as the selected object.<br/> * - When the selected item changes, the binding system gets triggered.<br/> * - When using a multiselect ListBox you need to ensure you are binding a collection. * <br/><br/> * When the {@link ListBox} has multiselect enabled, {@link #getValue()} returns an * {@link ArrayList} of String representing the selected values. <br/> * If you need a different collection type to be mapped create a {@link fr.lteconsulting.hexa.databinding.Converter}. * * @author Ben Dol */ public class ListBoxPropertyAdapter implements PropertyAdapter { private Logger logger = Logger.getLogger(ListBoxPropertyAdapter.class.getName()); private ListBox listBox; /** * Uses the given {@link ListBox} and acts as a binding property. * Used to bind the objects change value to another value. */ public ListBoxPropertyAdapter(ListBox listBox) { this.listBox = listBox; } @Override public void setValue(Object object) { deselectItems(); if (object instanceof Collection) { for (Object item : (Collection<?>) object) { selectItem(item); } } else { selectItem(object); } } @Override public Object getValue() { if(listBox.isMultipleSelect()) { List<String> selectedItems = new ArrayList<>(); for (int i = 0; i < listBox.getItemCount(); i++) { if (listBox.isItemSelected(i)) { selectedItems.add(listBox.getValue(i)); } } return selectedItems; } else { return listBox.getSelectedValue(); } } @Override public void removePropertyChangedHandler(Object handlerRegistration) { ((HandlerRegistration)handlerRegistration).removeHandler(); } @Override public Object registerPropertyChanged(final Action2<PropertyAdapter, Object> callback, final Object cookie) { return listBox.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { callback.exec(ListBoxPropertyAdapter.this, cookie); } }); } private void selectItem(Object item) { int index = getValueIndex(item); if (index > -1) { listBox.setItemSelected(index, true); } else { logger.warning("Failed to select item using: " + item.toString() + " " + item.getClass().getName()); } } private void deselectItems() { for(int i = 0; i < listBox.getItemCount(); i++) { if (listBox.isItemSelected(i)) { listBox.setItemSelected(i, false); } } } private int getValueIndex(Object value) { for(int i = 0; i < listBox.getItemCount(); i++) { if (listBox.getValue(i).equals(String.valueOf(value))) { return i; } } return -1; } }