/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.eas.widgets.boxes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.eas.ui.HasDecorationsWidth;
import com.google.gwt.dom.client.OptionElement;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.dom.client.Style;
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.i18n.client.HasDirection;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.ListBox;
/**
*
* @author mg
* @param <T>
*/
public class StyledListBox<T> extends ListBox implements HasValue<T>, HasDecorationsWidth {
protected List<T> associatedValues = new ArrayList<>();
protected Map<T, Integer> indicies;
protected T value;
public StyledListBox() {
this(false);
}
public StyledListBox(boolean isMultipleSelect) {
super();
setStyleName("form-control");
setMultipleSelect(isMultipleSelect);
addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (!isMultipleSelect()) {
int selected = getSelectedIndex();
if (selected == -1) {
setValue(null, true);
} else {
setValue(associatedValues.get(selected), true);
}
}
}
});
}
@Override
public void setDecorationsWidth(int aDecorationsWidth) {
getElement().getStyle().setPaddingRight(aDecorationsWidth, Style.Unit.PX);
}
public void addItem(String aLabel, String aKey, T aAssociatedValue, String aClassName) {
super.addItem(aLabel != null ? aLabel : "", aKey);
associatedValues.set(getItemCount() - 1, aAssociatedValue);
setItemStyleName(getItemCount() - 1, aClassName);
}
public void addItem(String aLabel, HasDirection.Direction dir, String aKey, T aAssociatedValue, String aClassName) {
super.addItem(aLabel != null ? aLabel : "", dir, aKey);
associatedValues.set(getItemCount() - 1, aAssociatedValue);
setItemStyleName(getItemCount() - 1, aClassName);
}
@Override
public void insertItem(String aLabel, HasDirection.Direction dir, String aKey, int index) {
boolean wasUnselected = getSelectedIndex() == -1;
super.insertItem(aLabel != null ? aLabel : "", dir, aKey, index);
if (wasUnselected)
super.setSelectedIndex(-1);
if (index == -1)// crazy gwt ListBox treats -1 as adding to the end
associatedValues.add(null);
else
associatedValues.add(index, null);
indicies = null;
}
@Override
public void removeItem(int index) {
super.removeItem(index);
associatedValues.remove(index);
indicies = null;
}
private void checkIndex(int index) {
if (index < 0 || index >= getItemCount()) {
throw new IndexOutOfBoundsException();
}
}
public OptionElement getItem(int aIndex) {
checkIndex(aIndex);
return getElement().<SelectElement> cast().getOptions().getItem(aIndex);
}
public T getAssociatedValue(int aIndex) {
checkIndex(aIndex);
return associatedValues.get(aIndex);
}
public void setAssociatedValue(int aIndex, T aValue) {
checkIndex(aIndex);
associatedValues.set(aIndex, aValue);
indicies = null;
}
public String getKey(int aIndex) {
OptionElement option = getItem(aIndex);
return option.getValue();
}
public String getItemStyleName(int aIndex) {
checkIndex(aIndex);
OptionElement option = getElement().<SelectElement> cast().getOptions().getItem(aIndex);
return option.getClassName();
}
public void setItemStyleName(int aIndex, String aValue) {
checkIndex(aIndex);
OptionElement option = getElement().<SelectElement> cast().getOptions().getItem(aIndex);
option.setClassName(aValue);
}
@Override
public void clear() {
super.clear();
associatedValues.clear();
indicies = null;
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<T> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
@Override
public T getValue() {
return value;
}
@Override
public void setValue(T aValue) {
setValue(aValue, false);
}
public String getText() {
int idx = indexOf(value);
if (idx != -1) {
return getItemText(idx);
} else {
return null;
}
}
public String getText(T aValue) {
validateLocator();
Integer idx = indicies.get(aValue);
if (idx != null) {
return getItemText(idx);
} else {
return null;
}
}
public int indexOf(T aValue) {
validateLocator();
Integer idx = indicies.get(aValue);
if (idx != null) {
return idx;
} else {
return -1;
}
}
@Override
public void setSelectedIndex(int index) {
super.setSelectedIndex(index);
}
@Override
public void setValue(T aValue, boolean fireEvents) {
if (value != aValue) {
value = aValue;
int index = indexOf(aValue);
setSelectedIndex(index);
if (fireEvents) {
ValueChangeEvent.fire(StyledListBox.this, value);
}
}
}
private void validateLocator() {
if (indicies == null) {
indicies = new HashMap<>();
for (int i = 0; i < associatedValues.size(); i++) {
T association = associatedValues.get(i);
indicies.put(association, i);
}
}
}
}