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());
}
}