- import com.google.gwt.dom.client.Style.Unit;
- import com.google.gwt.event.dom.client.ClickEvent;
- import com.google.gwt.event.dom.client.ClickHandler;
- 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.FlowPanel;
- import com.google.gwt.user.client.ui.FocusPanel;
- import com.google.gwt.user.client.ui.FocusWidget;
- import com.google.gwt.user.client.ui.HasValue;
- import com.google.gwt.user.client.ui.VerticalPanel;
- import com.google.gwt.user.client.ui.Widget;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- public class ComboBox<T extends Widget> extends FocusWidget implements
- HasValue<T> {
- private final List<T> items;
- private int selectedIndex = -1;
- private final FlowPanel display;
- private final PopupPanel popup;
- private final VerticalPanel popupListPanel;
- private final HashMap<T, FocusPanel> itemToWrapperMap;
- public ComboBox() {
- items = new ArrayList<T>();
- display = new FlowPanel();
- popup = new PopupPanel();
- popup.getElement().getStyle().setBorderWidth(1, Unit.PX);
- popup.getElement().getStyle().setPadding(0, Unit.PX);
- popup.setAutoHideEnabled(true);
- /*
- * Can only be used if you copied PopupPanel source and changed
- * visibility
- */
- // popup.setAnimationType(AnimationType.ROLL_DOWN);
- popupListPanel = new VerticalPanel();
- popup.add(popupListPanel);
- itemToWrapperMap = new HashMap<T, FocusPanel>();
- setElement(display.getElement());
- addClickHandler(new ClickHandler() {
- @Override
- public void onClick(final ClickEvent event) {
- if (!popup.isShowing()) {
- popup.setAnimationEnabled(true);
- popup.showRelativeTo(display);
- }
- }
- });
- }
- public List<T> getItems() {
- return items.subList(0, items.size() - 1);
- }
- public int indexOf(final T item) {
- return items.indexOf(item);
- }
- public int getItemCount() {
- return items.size();
- }
- public T getItem(final int index) {
- return items.get(index);
- }
- public void addItem(final T item) {
- items.add(item);
- if (selectedIndex == -1) {
- setSelectedIndex(items.indexOf(item));
- } else {
- addPopupItem(item);
- }
- }
- public void removeItem(final T item) {
- final int indexOf = items.indexOf(item);
- if (indexOf != -1) {
- items.remove(item);
- removePopupItem(item);
- if (indexOf == selectedIndex) {
- display.remove(item);
- }
- }
- }
- private void addPopupItem(final T item) {
- final FocusPanel itemWrapper = new FocusPanel();
- itemWrapper.add(item);
- itemWrapper.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(final ClickEvent event) {
- popup.setAnimationEnabled(false);
- popup.hide();
- setValue(item);
- }
- });
- itemToWrapperMap.put(item, itemWrapper);
- // Relayout popupPanel (sorted by add order)
- popupListPanel.clear();
- for (final T i : items) {
- final FocusPanel w = itemToWrapperMap.get(i);
- if (w != null) {
- popupListPanel.add(w);
- }
- }
- }
- private void removePopupItem(final T item) {
- final FocusPanel itemWrapper = itemToWrapperMap.remove(item);
- if (itemWrapper != null) {
- popupListPanel.remove(itemWrapper);
- }
- }
- public boolean setSelectedIndex(final int index) {
- final T item = items.get(index);
- if (item != null) {
- final T previous = getSelectedItem();
- removePopupItem(item);
- if (previous != null) {
- previous.removeFromParent();
- addPopupItem(previous);
- }
- selectedIndex = index;
- display.add(item);
- return true;
- }
- return false;
- }
- public void clear() {
- // Intentional copy (getItems() creates subList)
- for (final T item : getItems()) {
- removePopupItem(item);
- removeItem(item);
- }
- }
- public T getSelectedItem() {
- return getValue();
- }
- @Override
- public HandlerRegistration addValueChangeHandler(
- final ValueChangeHandler<T> handler) {
- return addHandler(handler, ValueChangeEvent.getType());
- }
- @Override
- public T getValue() {
- if (selectedIndex != -1) {
- return items.get(selectedIndex);
- }
- return null;
- }
- @Override
- public void setValue(final T value) {
- setValue(value, true);
- }
- @Override
- public void setValue(final T value, final boolean fireEvents) {
- if (setSelectedIndex(items.indexOf(value))) {
- if (fireEvents) {
- fireEvent(new ValueChangeEvent<T>(value) {
- });
- }
- }
- }
- }
GWT ComboBox for any kind of Widget