package com.turbomanage.gwt.client.ui.widget; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.ListBox; import java.util.ArrayList; import java.util.Collection; /** * A ListBox that can be populated with any Collection * * Published under Apache License v2 * * @author David Chandler * @param <T> */ public class SelectOneListBox<T> extends ListBox implements HasSelectedValue<T> { public interface OptionFormatter<T> { abstract String getLabel(T option); abstract String getValue(T option); } private boolean valueChangeHandlerInitialized; private T[] options; private OptionFormatter<T> formatter; public SelectOneListBox(Collection<T> selections, OptionFormatter<T> formatter) { setSelections(selections); setFormatter(formatter); } public SelectOneListBox(OptionFormatter<T> formatter) { this(new ArrayList<T>(), formatter); } public void setFormatter(OptionFormatter<T> formatter) { this.formatter = formatter; } @SuppressWarnings("unchecked") @Override public void setSelections(Collection<T> selections) { // Remember selected value T selectedValue = getSelectedValue(); // Remove prior options if (options != null) { int numItems = this.getItemCount(); int firstOption = numItems - options.length; for (int i=firstOption; i<numItems; i++) this.removeItem(firstOption); } options = (T[]) selections.toArray(); for (T option : options) { String optionLabel = formatter.getLabel(option); String optionValue = formatter.getValue(option); this.addItem(optionLabel, optionValue); } // Replace selected value setSelectedValue(selectedValue); } @Override public T getSelectedValue() { if (getSelectedIndex() >= 0) { String name = getValue(getSelectedIndex()); for (T option : options) { if (formatter.getValue(option).equals(name)) return option; } } return null; } private void setSelectedValue(T value) { if (value == null) return; for (int i=0; i < this.getItemCount(); i++) { String thisLabel = this.getItemText(i); if (formatter.getLabel(value).equals(thisLabel)) { this.setSelectedIndex(i); return; } } throw new IllegalArgumentException("No index found for value " + value.toString()); } /* * Methods to implement HasValue */ @Override public T getValue() { return this.getSelectedValue(); } @Override public void setValue(T value) { this.setValue(value, false); } @Override public void setValue(T value, boolean fireEvents) { T oldValue = getValue(); this.setSelectedValue(value); if (fireEvents) { ValueChangeEvent.fireIfNotEqual(this, oldValue, value); } } @Override public void clearSelectedValue() { this.setSelectedIndex(0); } @Override public HandlerRegistration addValueChangeHandler(ValueChangeHandler<T> handler) { // Initialization code if (!valueChangeHandlerInitialized) { valueChangeHandlerInitialized = true; super.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { ValueChangeEvent.fire(SelectOneListBox.this, getValue()); } }); } return addHandler(handler, ValueChangeEvent.getType()); } }