Rev 1233 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.tela_botanica.client.composants;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.tela_botanica.client.modeles.aDonnee;import org.tela_botanica.client.util.Debug;import org.tela_botanica.client.util.UtilString;import com.extjs.gxt.ui.client.GXT;import com.extjs.gxt.ui.client.Style.Scroll;import com.extjs.gxt.ui.client.core.El;import com.extjs.gxt.ui.client.core.XDOM;import com.extjs.gxt.ui.client.core.XTemplate;import com.extjs.gxt.ui.client.data.BaseModelData;import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;import com.extjs.gxt.ui.client.data.ModelData;import com.extjs.gxt.ui.client.data.PagingLoadConfig;import com.extjs.gxt.ui.client.data.PagingLoader;import com.extjs.gxt.ui.client.event.BaseEvent;import com.extjs.gxt.ui.client.event.ComponentEvent;import com.extjs.gxt.ui.client.event.DomEvent;import com.extjs.gxt.ui.client.event.Events;import com.extjs.gxt.ui.client.event.FieldEvent;import com.extjs.gxt.ui.client.event.ListViewEvent;import com.extjs.gxt.ui.client.event.Listener;import com.extjs.gxt.ui.client.event.PreviewEvent;import com.extjs.gxt.ui.client.event.SelectionChangedEvent;import com.extjs.gxt.ui.client.event.SelectionChangedListener;import com.extjs.gxt.ui.client.event.SelectionProvider;import com.extjs.gxt.ui.client.store.ListStore;import com.extjs.gxt.ui.client.store.StoreEvent;import com.extjs.gxt.ui.client.store.StoreListener;import com.extjs.gxt.ui.client.util.BaseEventPreview;import com.extjs.gxt.ui.client.util.DelayedTask;import com.extjs.gxt.ui.client.util.KeyNav;import com.extjs.gxt.ui.client.util.Util;import com.extjs.gxt.ui.client.widget.CheckBoxListView;import com.extjs.gxt.ui.client.widget.ComponentHelper;import com.extjs.gxt.ui.client.widget.LayoutContainer;import com.extjs.gxt.ui.client.widget.ListView;import com.extjs.gxt.ui.client.widget.form.ComboBox;import com.extjs.gxt.ui.client.widget.form.ListModelPropertyEditor;import com.extjs.gxt.ui.client.widget.form.PropertyEditor;import com.extjs.gxt.ui.client.widget.form.TriggerField;import com.extjs.gxt.ui.client.widget.form.ComboBox.ComboBoxMessages;import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;import com.extjs.gxt.ui.client.widget.form.TextField.TextFieldMessages;import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;import com.google.gwt.dom.client.Document;import com.google.gwt.dom.client.InputElement;import com.google.gwt.event.dom.client.KeyCodes;import com.google.gwt.user.client.Command;import com.google.gwt.user.client.DeferredCommand;import com.google.gwt.user.client.Element;import com.google.gwt.user.client.Event;import com.google.gwt.user.client.ui.RootPanel;public class ChampComboBoxMultiSelect<D extends ModelData> extends TriggerField<D> implements SelectionProvider<D> {/*** ComboBox error messages.*/public class ComboBoxMessages extends TextFieldMessages {private String loadingText = GXT.MESSAGES.loadMask_msg();private String valueNoutFoundText;/*** Returns the loading text.** @return the loading text*/public String getLoadingText() {return loadingText;}/*** Returns the value not found error text.** @return the error text*/public String getValueNoutFoundText() {return valueNoutFoundText;}/*** Sets the loading text.** @param loadingText the loading text*/public void setLoadingText(String loadingText) {this.loadingText = loadingText;}/*** When using a name/value combo, if the value passed to setValue is not* found in the store, valueNotFoundText will be displayed as the field text* if defined.** @param valueNoutFoundText*/public void setValueNoutFoundText(String valueNoutFoundText) {this.valueNoutFoundText = valueNoutFoundText;}}/*** TriggerAction enum.*/public enum TriggerAction {ALL, QUERY;}protected boolean autoComplete = false;protected boolean delayedCheck;protected String lastQuery;protected ListStore<D> store;private String allQuery = "";private BaseEventPreview eventPreview;private boolean expanded;private El footer;private boolean forceSelection;private InputElement hiddenInput;private String itemSelector;private String lastSelectionText;private boolean lazyRender = true, initialized;private LayoutContainer list;private String listAlign = "tl-bl?";private String listStyle = "x-combo-list";private int maxHeight = 300;private int minChars = 4;private int minListWidth = 70;private String mode = "remote";private int pageSize;private PagingToolBar pageTb;private int queryDelay = 500;private D selectedItem;private String selectedStyle = "x-combo-selected";private StoreListener<D> storeListener;private DelayedTask taTask, dqTask;private XTemplate template;private TriggerAction triggerAction = TriggerAction.QUERY;private boolean typeAhead;private int typeAheadDelay = 250;private boolean useQueryCache = true;private String valueField;//+----------------------------------------------------------------------------------------------------------------+// Attributs modifiés ou ajoutésprivate CheckBoxListView<D> listView = null;private String valueFieldSeparator = aDonnee.SEPARATEUR_VALEURS;private String rawSeparator = ", ";private List<D> listeInitiale = new ArrayList<D>();private boolean initialisation = false;private boolean premierAppel = true;//+----------------------------------------------------------------------------------------------------------------+//+----------------------------------------------------------------------------------------------------------------+// Constructeur modifiéspublic ChampComboBoxMultiSelect() {messages = new ComboBoxMessages();listView = new CheckBoxListView<D>();setPropertyEditor(new ListModelPropertyEditor<D>());monitorWindowResize = true;windowResizeDelay = 0;initComponent();setTriggerAction(TriggerAction.ALL);}//+----------------------------------------------------------------------------------------------------------------+public void addSelectionChangedListener(SelectionChangedListener<D> listener) {addListener(Events.SelectionChange, listener);}@Overridepublic void clear() {getStore().clearFilters();boolean f = forceSelection;forceSelection = false;super.clear();forceSelection = f;}/*** Clears any text/value currently set in the field.*/public void clearSelections() {setRawValue("");lastSelectionText = "";applyEmptyText();value = null;}/*** Execute a query to filter the dropdown list. Fires the BeforeQuery event* prior to performing the query allowing the query action to be canceled if* needed.** @param q the query* @param forceAll true to force the query to execute even if there are* currently fewer characters in the field than the minimum specified* by the minChars config option. It also clears any filter* previously saved in the current store*/public void doQuery(String q, boolean forceAll) {if (q == null) {q = "";}FieldEvent fe = new FieldEvent(this);fe.setValue(q);if (!fireEvent(Events.BeforeQuery, fe)) {return;}if (forceAll || q.length() >= minChars) {if (!useQueryCache || !q.equals(lastQuery)) {lastQuery = q;if (mode.equals("local")) {selectedItem = null;store.filter(getDisplayField(), q);onLoad(null);} else {expand();store.getLoader().load(getParams(q));}} else {selectedItem = null;onLoad(null);}}}/*** Returns the all query.** @return the all query*/public String getAllQuery() {return allQuery;}/*** Returns the display field.** @return the display field*/public String getDisplayField() {return getPropertyEditor().getDisplayProperty();}/*** Returns true if the field's value is forced to one of the value in the* list.** @return the force selection state*/public boolean getForceSelection() {return forceSelection;}/*** Returns the item selector.** @return the item selector*/public String getItemSelector() {return itemSelector;}/*** Returns the list's list align value.** @return the list align value*/public String getListAlign() {return listAlign;}/*** Returns the list style.** @return the list style*/public String getListStyle() {return listStyle;}/*** Returns the loading text.** @return the loading text*/public String getLoadingText() {return getMessages().getLoadingText();}/*** Returns the dropdown list's max height.** @return the max height*/public int getMaxHeight() {return maxHeight;}@Overridepublic ComboBoxMessages getMessages() {return (ComboBoxMessages) messages;}/*** Returns the min characters used for autocompete and typeahead.** @return the minimum number of characters*/public int getMinChars() {return minChars;}/*** Returns the dropdown list's min width.** @return the min width*/public int getMinListWidth() {return minListWidth;}/*** Returns the page size.** @return the page size*/public int getPageSize() {return pageSize;}/*** Returns the combo's paging tool bar.** @return the tool bar*/public PagingToolBar getPagingToolBar() {return pageTb;}@Overridepublic ListModelPropertyEditor<D> getPropertyEditor() {return (ListModelPropertyEditor<D>) propertyEditor;}/*** Returns the query delay.** @return the query delay*/public int getQueryDelay() {return queryDelay;}/*** Returns the selected style.** @return the selected style*/public String getSelectedStyle() {return selectedStyle;}/*** Returns the combo's store.** @return the store*/public ListStore<D> getStore() {return store;}/*** Returns the custom template.** @return the template*/public XTemplate getTemplate() {return template;}/*** Returns the trigger action.** @return the trigger action*/public TriggerAction getTriggerAction() {return triggerAction;}/*** Returns the type ahead delay in milliseconds.** @return the type ahead delay*/public int getTypeAheadDelay() {return typeAheadDelay;}/*** Returns the value field name.** @return the value field name*/public String getValueField() {return valueField;}/*** Returns <code>true</code> if the panel is expanded.** @return the expand state*/public boolean isExpanded() {return expanded;}/*** Returns true if lazy rendering is enabled.** @return true of lazy rendering*/public boolean isLazyRender() {return lazyRender;}/*** Returns true if type ahead is enabled.** @return the type ahead state*/public boolean isTypeAhead() {return typeAhead;}/*** Returns the state if the query cache is used or not.** @return the useQueryCache state*/public boolean isUseQueryCache() {return useQueryCache;}public void removeSelectionListener(SelectionChangedListener<D> listener) {removeListener(Events.SelectionChange, listener);}@Overridepublic void reset() {getStore().clearFilters();boolean f = forceSelection;forceSelection = false;super.reset();forceSelection = f;}public void select(D sel) {if (listView != null && sel != null) {int index = store.indexOf(sel);selectedItem = sel;if (index < listView.getElements().size()) {listView.getSelectionModel().select(sel, false);fly(listView.getElement(index)).scrollIntoView(listView.getElement(), false);}}}/*** Select an item in the dropdown list by its numeric index in the list. This* function does NOT cause the select event to fire. The list must expanded* for this function to work, otherwise use #setValue.** @param index the index of the item to select*/public void select(int index) {select(store.getAt(index));}/*** The text query to send to the server to return all records for the list* with no filtering (defaults to '').** @param allQuery the all query*/public void setAllQuery(String allQuery) {this.allQuery = allQuery;}/*** The underlying data field name to bind to this ComboBox (defaults to* 'text').** @param displayField the display field*/public void setDisplayField(String displayField) {getPropertyEditor().setDisplayProperty(displayField);}/*** Sets the panel's expand state.** @param expand <code>true<code> true to expand*/public void setExpanded(boolean expand) {this.expanded = expand;if (isRendered()) {if (expand) {expand();} else {collapse();}}}/*** Sets whether the combo's value is restricted to one of the values in the* list, false to allow the user to set arbitrary text into the field* (defaults to false).** @param forceSelection true to force selection*/public void setForceSelection(boolean forceSelection) {this.forceSelection = forceSelection;}/*** This setting is required if a custom XTemplate has been specified.** @param itemSelector the item selector*/public void setItemSelector(String itemSelector) {this.itemSelector = itemSelector;}/*** True to lazily render the combo's drop down list (default to true,* pre-render).** @param lazyRender true to lazy render the drop down list*/public void setLazyRender(boolean lazyRender) {this.lazyRender = lazyRender;}/*** Sets a valid anchor position value. See {@link El#alignTo} for details on* supported anchor positions (defaults to 'tl-bl?').** @param listAlign the new list align value*/public void setListAlign(String listAlign) {this.listAlign = listAlign;}/*** Sets the style for the drop down list (defaults to 'x-combo-list');** @param listStyle the list style*/public void setListStyle(String listStyle) {this.listStyle = listStyle;}/*** Sets the loading text.** @param loadingText the loading text*/public void setLoadingText(String loadingText) {getMessages().setLoadingText(loadingText);}/*** Sets the maximum height in pixels of the dropdown list before scrollbars* are shown (defaults to 300).** @param maxHeight the max hieght*/public void setMaxHeight(int maxHeight) {this.maxHeight = maxHeight;}/*** Sets the minimum number of characters the user must type before* autocomplete and typeahead active (defaults to 4 if remote, or 0 if local).** @param minChars*/public void setMinChars(int minChars) {this.minChars = minChars;}/*** Sets the minimum width of the dropdown list in pixels (defaults to 70, will* be ignored if listWidth has a higher value).** @param minListWidth the min width*/public void setMinListWidth(int minListWidth) {this.minListWidth = minListWidth;}/*** Sets the page size. Only applies when using a paging toolbar.** @param pageSize the page size*/public void setPageSize(int pageSize) {assertPreRender();this.pageSize = pageSize;if (pageSize > 0) {if (pageTb != null) {pageTb.setPageSize(pageSize);} else {pageTb = new PagingToolBar(pageSize);}} else {pageTb = null;}}@Overridepublic void setPropertyEditor(PropertyEditor<D> propertyEditor) {assert propertyEditor instanceof ListModelPropertyEditor<?> : "PropertyEditor must be a ListModelPropertyEditor instance";super.setPropertyEditor(propertyEditor);}/*** The length of time in milliseconds to delay between the start of typing and* sending the query to filter the dropdown list.** @param queryDelay the query delay*/public void setQueryDelay(int queryDelay) {this.queryDelay = queryDelay;}@Overridepublic void setRawValue(String text) {if (rendered) {if (text == null) {String msg = getMessages().getValueNoutFoundText();text = msg != null ? msg : "";}getInputEl().setValue(text);}}/*** Sets the CSS style name to apply to the selected item in the dropdown list* (defaults to 'x-combo-selected').** @param selectedStyle the selected style*/public void setSelectedStyle(String selectedStyle) {this.selectedStyle = selectedStyle;}/*** Sets the template fragment to be used for the text of each combo list item.** <pre>** <code> combo.setSimpleTemplate("{abbr} {name}"); </code>** </pre>** @param html the html used only for the text of each item in the list*/public void setSimpleTemplate(String html) {assertPreRender();html = "<tpl for=\".\"><div class=x-combo-list-item>" + html + "</div></tpl>";template = XTemplate.create(html);}/*** Sets the combo's store.** @param store the store*/public void setStore(ListStore<D> store) {this.store = store;}/*** Sets the custom template used to render the combo's drop down list.Use this* to create custom UI layouts for items in the list.* <p>* If you wish to preserve the default visual look of list items, add the CSS* class name 'x-combo-list-item' to the template's container element.** @param html the html*/public void setTemplate(String html) {assertPreRender();template = XTemplate.create(html);}/*** Sets the custom template used to render the combo's drop down list.** @param template the template*/public void setTemplate(XTemplate template) {assertPreRender();this.template = template;}/*** The action to execute when the trigger field is activated. Use* {@link TriggerAction#ALL} to run the query specified by the allQuery config* option (defaults to {@link TriggerAction#QUERY}).** @param triggerAction the trigger action*/public void setTriggerAction(TriggerAction triggerAction) {this.triggerAction = triggerAction;}/*** True to populate and autoselect the remainder of the text being typed after* a configurable delay ({@link #typeAheadDelay}) if it matches a known value* (defaults to false)** @param typeAhead*/public void setTypeAhead(boolean typeAhead) {this.typeAhead = typeAhead;if (rendered) {if (typeAhead && taTask == null) {taTask = new DelayedTask(new Listener<BaseEvent>() {public void handleEvent(BaseEvent be) {onTypeAhead();}});} else if (!typeAhead && taTask != null) {taTask.cancel();taTask = null;}}}/*** The length of time in milliseconds to wait until the typeahead text is* displayed if typeAhead = true (defaults to 250).** @param typeAheadDelay the type ahead delay*/public void setTypeAheadDelay(int typeAheadDelay) {this.typeAheadDelay = typeAheadDelay;}/*** Set this to false to disable the last query cache (defaults to true).** When set to false the store gets queried on each expand for the data that* should get displayed in the list. If you use a loader, than each time the* ComboBox gets expanded, the server gets asked for the data.** You want to do this for example, if you filter the content of this ComboBox* against some selection in another field.** @param useQueryCache the useQueryCache to set*/public void setUseQueryCache(boolean useQueryCache) {this.useQueryCache = useQueryCache;}/*** Sets the model field used to retrieve the "value" from the model. If* specified, a hidden form field will contain the value. The hidden form* field name will be the combo's field name plus "-hidden".** @param valueField the value field name*/public void setValueField(String valueField) {this.valueField = valueField;}protected void collapseIf(PreviewEvent pe) {if (!list.el().isOrHasChild(pe.getTarget()) && !el().isOrHasChild(pe.getTarget())) {collapse();}}protected D findModel(String property, String value) {if (value == null) return null;for (D model : store.getModels()) {if (value.equals(getPropertyEditor().getStringValue(model))) {return model;}}return null;}protected void fireKey(FieldEvent fe) {if (fe.isNavKeyPress() && !isExpanded() && !delayedCheck) {fireEvent(Events.SpecialKey, fe);}}@Overrideprotected El getFocusEl() {return input;}protected PagingLoadConfig getParams(String query) {BasePagingLoadConfig config = new BasePagingLoadConfig();config.setLimit(pageSize);config.setOffset(0);config.set("query", query);return config;}protected boolean hasFocus() {return hasFocus || expanded;}@SuppressWarnings("unchecked")protected void initComponent() {storeListener = new StoreListener<D>() {@Overridepublic void storeBeforeDataChanged(StoreEvent<D> se) {onBeforeLoad(se);}@Overridepublic void storeDataChanged(StoreEvent<D> se) {onLoad(se);}};eventPreview = new BaseEventPreview() {@Overrideprotected boolean onPreview(PreviewEvent pe) {switch (pe.getType().getEventCode()) {case Event.ONSCROLL:case Event.ONMOUSEWHEEL:case Event.ONMOUSEDOWN:collapseIf(pe);}return true;}};eventPreview.setAutoHide(false);new KeyNav(this) {public void onDown(ComponentEvent ce) {ce.cancelBubble();if (!isExpanded()) {onTriggerClick(ce);} else {selectNext();}}@Overridepublic void onEnter(ComponentEvent ce) {if (expanded) {ce.cancelBubble();onViewClick(ce, false);delayedCheck = true;unsetDelayCheck();}}@Overridepublic void onEsc(ComponentEvent ce) {if (expanded) {ce.cancelBubble();collapse();}}@Overridepublic void onTab(ComponentEvent ce) {if (expanded) {onViewClick(ce, false);}}@Overridepublic void onUp(ComponentEvent ce) {if (expanded) {ce.cancelBubble();selectPrev();}}};}protected void onBeforeLoad(StoreEvent<D> se) {if (!hasFocus()) {return;}if (expanded) {restrict();}}@Overrideprotected void onDetach() {collapse();super.onDetach();if (eventPreview != null) {eventPreview.remove();}}protected void onEmptyResults() {collapse();}@Overrideprotected void onKeyDown(FieldEvent fe) {if (fe.getKeyCode() == KeyCodes.KEY_TAB) {if (expanded) {onViewClick(fe, false);}}super.onKeyDown(fe);}@Overrideprotected void onKeyUp(FieldEvent fe) {super.onKeyUp(fe);if (isEditable() && (!fe.isSpecialKey() || fe.getKeyCode() == KeyCodes.KEY_BACKSPACE || fe.getKeyCode() == 46)) {// last keydqTask.delay(queryDelay);}}protected void onLoad(StoreEvent<D> se) {if (!isAttached() || !hasFocus()) {return;}if (store.getCount() > 0) {if (expanded) {restrict();} else {expand();}if (lastQuery != null && lastQuery.equals(allQuery)) {if (isEditable()) {selectAll();}} else {if (typeAhead) {taTask.delay(typeAheadDelay);}}if (!selectByValue(getRawValue())) {select(0);}} else {onEmptyResults();}}protected void onRender(Element parent, int index) {super.onRender(parent, index);initList();if (!autoComplete) {getInputEl().dom.setAttribute("autocomplete", "off");}if (mode.equals("local")) {minChars = 0;}dqTask = new DelayedTask(new Listener<BaseEvent>() {public void handleEvent(BaseEvent be) {initQuery();}});if (valueField != null) {hiddenInput = Document.get().createHiddenInputElement().cast();hiddenInput.setName(getName() + "-hidden");getElement().appendChild(hiddenInput);}if (typeAhead) {taTask = new DelayedTask(new Listener<BaseEvent>() {public void handleEvent(BaseEvent be) {onTypeAhead();}});}eventPreview.getIgnoreList().add(getElement());}protected void onSelect(D model, int index) {FieldEvent fe = new FieldEvent(this);if (fireEvent(Events.BeforeSelect, fe)) {setValue(model);collapse();fireEvent(Events.Select, fe);}}protected void onTriggerClick(ComponentEvent ce) {super.onTriggerClick(ce);if (expanded) {collapse();} else {onFocus(null);if (triggerAction == TriggerAction.ALL) {doQuery(allQuery, true);} else {doQuery(getRawValue(), true);}}getInputEl().focus();}protected void onTypeAhead() {if (store.getCount() > 0) {D m = store.getAt(0);String newValue = propertyEditor.getStringValue(m);int len = newValue.length();int selStart = getRawValue().length();if (selStart != len) {setRawValue(newValue);select(selStart, newValue.length());}}}protected void onViewClick(DomEvent de, boolean focus) {int idx = -1;// when testing in selenium the items will not be selected as the mouse// is not moved during the testElement elem = listView.findElement(de.getTarget());if (elem != null) {idx = listView.indexOf(elem);} else {D sel = listView.getSelectionModel().getSelectedItem();if (sel != null) {idx = store.indexOf(sel);}}if (idx != -1) {D sel = store.getAt(idx);onSelect(sel, idx);}if (focus) {DeferredCommand.addCommand(new Command() {public void execute() {focus();}});}}protected void onWindowResize(int width, int height) {collapse();}@Overrideprotected void triggerBlur(ComponentEvent ce) {doForce();super.triggerBlur(ce);}protected void unsetDelayCheck() {DeferredCommand.addCommand(new Command() {public void execute() {delayedCheck = false;}});}@Overrideprotected boolean validateBlur(DomEvent e, Element target) {return list == null || (list != null && !list.isVisible() && !list.getElement().isOrHasChild(target));}@Overrideprotected boolean validateValue(String value) {if (forceSelection) {boolean f = forceSelection;forceSelection = false;if (getValue() == null) {forceSelection = f;String rv = getRawValue();if (getAllowBlank() && (rv == null || rv.equals(""))) {return true;}markInvalid(getMessages().getBlankText());return false;}forceSelection = f;}return super.validateValue(value);}private void createList(boolean remove) {RootPanel.get().add(list);initialized = true;if (remove) {RootPanel.get().remove(list);}}private void initQuery() {doQuery(getRawValue(), false);}private void restrict() {list.el().setVisibility(false);listView.setHeight("auto");list.setHeight("auto");int w = Math.max(getWidth(), minListWidth);int fh = footer != null ? footer.getHeight() : 0;int fw = list.el().getFrameWidth("tb") + fh;int h = listView.getHeight() + fw;h = Math.min(h, maxHeight - fw);list.setSize(w, h);list.el().makePositionable(true);list.el().alignTo(getElement(), listAlign, null);h -= fh;int width = w - list.el().getFrameWidth("lr");listView.syncSize();listView.setSize(width, h - list.el().getFrameWidth("tb"));if (pageTb != null) {pageTb.setWidth(width);}int y = list.el().getY();int b = y + h;int vh = XDOM.getViewportSize().height + XDOM.getBodyScrollTop();if (b > vh) {y = y - (b - vh) - 5;list.el().setTop(y);}list.el().setVisibility(true);}private boolean selectByValue(String value) {D r = findModel(getDisplayField(), value);if (r != null) {select(r);return true;}return false;}private void selectNext() {int count = store.getCount();if (count > 0) {int selectedIndex = store.indexOf(selectedItem);if (selectedIndex == -1) {select(0);} else if (selectedIndex < count - 1) {select(selectedIndex + 1);}}}private void selectPrev() {int count = store.getCount();if (count > 0) {int selectedIndex = store.indexOf(selectedItem);if (selectedIndex == -1) {select(0);} else if (selectedIndex != 0) {select(selectedIndex - 1);}}}//+--------------------------------------------------------------------------------------------------------------------+// Méthode modifiées@Overridepublic D getValue() {return (D) new BaseModelData();}@Overridepublic void setValue(D value) {}public List<D> getSelection() {List<D> sel = new ArrayList<D>();if (listeInitiale != null && initialisation == false) {sel = listeInitiale;if (listView.isRendered()) {initialisation = true;}} else if (listView.isRendered()) {sel = listView.getChecked();}return sel;}public void setSelection(List<D> selection) {nettoyerListeDeCasesACocher();for (D d : selection) {listView.setChecked(d, true);}}/*** Returns the combo's list view.** @return the view*/public CheckBoxListView<D> getListView() {return listView;}/*** Returns the combo's list view.** @return the view*/public CheckBoxListView<D> getView() {return listView;}/*** Sets the combo's view.** @param view the view*/public void setView(CheckBoxListView<D> view) {this.listView = view;}public String getRawSeparator() {return rawSeparator;}public void setRawSeparator(String rawSeparator) {this.rawSeparator = rawSeparator;}public void setValueFieldSeparator(String valueFieldSeparator) {this.valueFieldSeparator = valueFieldSeparator;}public String getValueFieldSeparator() {return valueFieldSeparator;}/*** Hides the dropdown list if it is currently expanded. Fires the* <i>Collapse</i> event on completion.*/public void collapse() {if (!expanded) {return;}eventPreview.remove();expanded = false;list.hide();RootPanel.get().remove(list);fireEvent(Events.Collapse, new FieldEvent(this));mettreAJour("collapse");}/*** Expands the dropdown list if it is currently hidden. Fires the* <i>expand</i> event on completion.*/public void expand() {if (expanded || !hasFocus) {return;}expanded = true;if (!initialized) {createList(false);} else {RootPanel.get().add(list);}list.show();list.layout();list.el().updateZIndex(0);restrict();eventPreview.add();fireEvent(Events.Expand, new FieldEvent(this));if (premierAppel) {premierAppel = false;collapse();expand();}}protected void initList() {if (listView == null) {setView(new CheckBoxListView<D>());}String style = getListStyle();listView.setStyleAttribute("overflowX", "hidden");listView.setStyleName(style + "-inner");listView.setStyleAttribute("padding", "0px");listView.setSelectOnOver(true);listView.setBorders(false);listView.setStyleAttribute("backgroundColor", "white");listView.setSelectStyle(getSelectedStyle());listView.setLoadingText(getLoadingText());if (getTemplate() == null) {listView.setDisplayProperty(getDisplayField());} else {listView.setTemplate(getTemplate());}setMaxHeight(0);list = new LayoutContainer() {@Overrideprotected void onRender(Element parent, int index) {super.onRender(parent, index);eventPreview.getIgnoreList().add(getElement());}};list.setScrollMode(Scroll.NONE);list.setShim(true);list.setShadow(true);list.setBorders(true);list.setStyleName(style);list.hide();assert store != null : "ComboBox needs a store";list.add(listView);listView.show();if (!lazyRender) {createList(true);}bindStore(store, true);};protected void doForce() {}private void bindStore(ListStore<D> store, boolean initial) {if (this.store != null && !initial) {this.store.removeStoreListener(storeListener);if (store == null) {this.store = null;if (listView != null) {listView.setStore(null);}}}if (store != null) {this.store = store;if (store.getLoader() == null) {mode = "local";}if (listView != null) {listView.setStore(store);}store.addStoreListener(storeListener);}}private void updateHiddenValue() {if (hiddenInput != null) {hiddenInput.setValue(collecterIdentifiants());}}private void mettreAJour(String origine) {setSelection(getSelection());setRawValue(collecterTexte());updateHiddenValue();}private void nettoyerListeDeCasesACocher() {if (listView.isRendered()) {List<D> listeADecocher = listView.getChecked();for (D d : listeADecocher) {listView.setChecked(d, false);}}}public void peupler(String identifiants) {peuplerAvecIdentifiant(identifiants);}public void peuplerAvecIdentifiant(String identifiants) {List<D> liste = parserChaine(identifiants, valueFieldSeparator, getValueField());executerPeuplement(liste);}public void peuplerAvecTexte(String texte) {List<D> liste = parserChaine(texte, rawSeparator, getDisplayField());executerPeuplement(liste);}private void executerPeuplement(List<D> liste) {listeInitiale = liste;initialisation = false;mettreAJour("executerPeuplement");}public String collecter() {return collecterIdentifiants();}public String collecterIdentifiants() {return executerCollecte(getSelection(), getValueField(), valueFieldSeparator);}public String collecterTexte() {return executerCollecte(getSelection(), getDisplayField(), rawSeparator);}private String executerCollecte(List<D> selection, String champCle, String separateur) {String chaineDeSortie = "";Iterator<D> it = selection.iterator();while (it.hasNext()) {D d = it.next();chaineDeSortie += d.get(champCle);if (it.hasNext()) {chaineDeSortie += separateur;}}return chaineDeSortie;}private List<D> parserChaine(String chaineAAnalyser, String separateur, String champCle) {ArrayList<D> liste = new ArrayList<D>();chaineAAnalyser = chaineAAnalyser.trim();if (!UtilString.isEmpty(chaineAAnalyser)) {String[] valeurs = chaineAAnalyser.split(separateur);int nbreValeurs = valeurs.length;if (nbreValeurs > 0 && getStore() != null) {for (int i = 0; i < nbreValeurs; i++) {String valeur = valeurs[i];D d = getStore().findModel(champCle, valeur);liste.add(d);}}}return liste;}public String formaterTexteEnIdentifiants(String texte) {List<D> liste = parserChaine(texte, rawSeparator, getDisplayField());return executerCollecte(liste, getValueField(), valueFieldSeparator);}public String formaterIdentifiantsEnTexte(String identifiants) {List<D> liste = parserChaine(identifiants, valueFieldSeparator, getValueField());return executerCollecte(liste, getDisplayField(), rawSeparator);}}