123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
-
- package com.itmill.toolkit.terminal.gwt.client.ui;
-
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Date;
- import java.util.Iterator;
-
- import com.google.gwt.user.client.Command;
- import com.google.gwt.user.client.DOM;
- import com.google.gwt.user.client.Element;
- import com.google.gwt.user.client.Event;
- import com.google.gwt.user.client.Window;
- import com.google.gwt.user.client.ui.ClickListener;
- import com.google.gwt.user.client.ui.Composite;
- import com.google.gwt.user.client.ui.FlowPanel;
- import com.google.gwt.user.client.ui.FocusListener;
- import com.google.gwt.user.client.ui.HTML;
- import com.google.gwt.user.client.ui.Image;
- import com.google.gwt.user.client.ui.KeyboardListener;
- import com.google.gwt.user.client.ui.PopupListener;
- import com.google.gwt.user.client.ui.PopupPanel;
- import com.google.gwt.user.client.ui.TextBox;
- import com.google.gwt.user.client.ui.Widget;
- import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
- import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
- import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
- import com.itmill.toolkit.terminal.gwt.client.Focusable;
- import com.itmill.toolkit.terminal.gwt.client.Paintable;
- import com.itmill.toolkit.terminal.gwt.client.UIDL;
- import com.itmill.toolkit.terminal.gwt.client.Util;
-
- /**
- *
- * TODO needs major refactoring (to be extensible etc)
- */
- public class IFilterSelect extends Composite implements Paintable, Field,
- KeyboardListener, ClickListener, FocusListener, Focusable {
-
- public class FilterSelectSuggestion implements Suggestion, Command {
-
- private final String key;
- private final String caption;
- private String iconUri;
-
- public FilterSelectSuggestion(UIDL uidl) {
- key = uidl.getStringAttribute("key");
- caption = uidl.getStringAttribute("caption");
- if (uidl.hasAttribute("icon")) {
- iconUri = client.translateToolkitUri(uidl
- .getStringAttribute("icon"));
- }
- }
-
- public String getDisplayString() {
- final StringBuffer sb = new StringBuffer();
- if (iconUri != null) {
- sb.append("<img src=\"");
- sb.append(iconUri);
- sb.append("\" alt=\"icon\" class=\"i-icon\" />");
- }
- sb.append(Util.escapeHTML(caption));
- return sb.toString();
- }
-
- public String getReplacementString() {
- return caption;
- }
-
- public int getOptionKey() {
- return Integer.parseInt(key);
- }
-
- public String getIconUri() {
- return iconUri;
- }
-
- public void execute() {
- onSuggestionSelected(this);
- }
- }
-
- /**
- * @author mattitahvonen
- *
- */
- public class SuggestionPopup extends ToolkitOverlay implements
- PositionCallback, PopupListener {
- private static final int EXTRASPACE = 8;
-
- private static final String Z_INDEX = "30000";
-
- private final SuggestionMenu menu;
-
- private final Element up = DOM.createDiv();
- private final Element down = DOM.createDiv();
- private final Element status = DOM.createDiv();
-
- private boolean isPagingEnabled = true;
-
- private long lastAutoClosed;
-
- SuggestionPopup() {
- super(true);
- menu = new SuggestionMenu();
- setWidget(menu);
- setStyleName(CLASSNAME + "-suggestpopup");
- DOM.setStyleAttribute(getElement(), "zIndex", Z_INDEX);
-
- final Element root = getContainerElement();
-
- DOM.setInnerHTML(up, "<span>Prev</span>");
- DOM.sinkEvents(up, Event.ONCLICK);
- DOM.setInnerHTML(down, "<span>Next</span>");
- DOM.sinkEvents(down, Event.ONCLICK);
- DOM.insertChild(root, up, 0);
- DOM.appendChild(root, down);
- DOM.appendChild(root, status);
- DOM.setElementProperty(status, "className", CLASSNAME + "-status");
-
- addPopupListener(this);
- }
-
- public void showSuggestions(Collection currentSuggestions,
- int currentPage, int totalSuggestions) {
-
- if (ApplicationConnection.isTestingMode()) {
- // Add TT anchor point
- DOM.setElementProperty(getElement(), "id", paintableId
- + "_OPTIONLIST");
- }
-
- menu.setSuggestions(currentSuggestions);
- final int x = IFilterSelect.this.getAbsoluteLeft();
- int y = tb.getAbsoluteTop();
- y += tb.getOffsetHeight();
- setPopupPosition(x, y);
- final int first = currentPage * PAGELENTH
- + (nullSelectionAllowed && currentPage > 0 ? 0 : 1);
- final int last = first + currentSuggestions.size() - 1;
- final int matches = totalSuggestions
- - (nullSelectionAllowed ? 1 : 0);
- if (last > 0) {
- // nullsel not counted, as requested by user
- DOM.setInnerText(status, (totalSuggestions == 0 ? 0 : first)
- + "-"
- + ("".equals(lastFilter) && nullSelectionAllowed
- && currentPage == 0 ? last - 1 : last) + "/"
- + matches);
- } else {
- DOM.setInnerText(status, "");
- }
- setPrevButtonActive(first > 1);
- setNextButtonActive(last < matches);
-
- // clear previously fixed width
- menu.setWidth("");
- DOM.setStyleAttribute(DOM.getFirstChild(menu.getElement()),
- "width", "");
-
- setPopupPositionAndShow(this);
- }
-
- private void setNextButtonActive(boolean b) {
- if (b) {
- DOM.sinkEvents(down, Event.ONCLICK);
- DOM.setElementProperty(down, "className", CLASSNAME
- + "-nextpage");
- } else {
- DOM.sinkEvents(down, 0);
- DOM.setElementProperty(down, "className", CLASSNAME
- + "-nextpage-off");
- }
- }
-
- private void setPrevButtonActive(boolean b) {
- if (b) {
- DOM.sinkEvents(up, Event.ONCLICK);
- DOM
- .setElementProperty(up, "className", CLASSNAME
- + "-prevpage");
- } else {
- DOM.sinkEvents(up, 0);
- DOM.setElementProperty(up, "className", CLASSNAME
- + "-prevpage-off");
- }
-
- }
-
- public void selectNextItem() {
- final MenuItem cur = menu.getSelectedItem();
- final int index = 1 + menu.getItems().indexOf(cur);
- if (menu.getItems().size() > index) {
- final MenuItem newSelectedItem = (MenuItem) menu.getItems()
- .get(index);
- menu.selectItem(newSelectedItem);
- tb.setText(newSelectedItem.getText());
- tb.setSelectionRange(lastFilter.length(), newSelectedItem
- .getText().length()
- - lastFilter.length());
-
- } else if (hasNextPage()) {
- filterOptions(currentPage + 1, lastFilter);
- }
- }
-
- public void selectPrevItem() {
- final MenuItem cur = menu.getSelectedItem();
- final int index = -1 + menu.getItems().indexOf(cur);
- if (index > -1) {
- final MenuItem newSelectedItem = (MenuItem) menu.getItems()
- .get(index);
- menu.selectItem(newSelectedItem);
- tb.setText(newSelectedItem.getText());
- tb.setSelectionRange(lastFilter.length(), newSelectedItem
- .getText().length()
- - lastFilter.length());
- } else if (index == -1) {
- if (currentPage > 0) {
- filterOptions(currentPage - 1, lastFilter);
- }
- } else {
- final MenuItem newSelectedItem = (MenuItem) menu.getItems()
- .get(menu.getItems().size() - 1);
- menu.selectItem(newSelectedItem);
- tb.setText(newSelectedItem.getText());
- tb.setSelectionRange(lastFilter.length(), newSelectedItem
- .getText().length()
- - lastFilter.length());
- }
- }
-
- public void onBrowserEvent(Event event) {
- final Element target = DOM.eventGetTarget(event);
- if (DOM.compare(target, up)
- || DOM.compare(target, DOM.getChild(up, 0))) {
- filterOptions(currentPage - 1, lastFilter);
- } else if (DOM.compare(target, down)
- || DOM.compare(target, DOM.getChild(down, 0))) {
- filterOptions(currentPage + 1, lastFilter);
- }
- tb.setFocus(true);
- }
-
- public void setPagingEnabled(boolean paging) {
- if (isPagingEnabled == paging) {
- return;
- }
- if (paging) {
- DOM.setStyleAttribute(down, "display", "block");
- DOM.setStyleAttribute(up, "display", "block");
- DOM.setStyleAttribute(status, "display", "block");
- } else {
- DOM.setStyleAttribute(down, "display", "none");
- DOM.setStyleAttribute(up, "display", "none");
- DOM.setStyleAttribute(status, "display", "none");
- }
- isPagingEnabled = paging;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.google.gwt.user.client.ui.PopupPanel$PositionCallback#setPosition(int,
- * int)
- */
- public void setPosition(int offsetWidth, int offsetHeight) {
-
- int top = -1;
- int left = -1;
-
- // reset menu size and retrieve its "natural" size
- menu.setHeight("");
- if (currentPage > 0) {
- // fix height to avoid height change when getting to last page
- menu.fixHeightTo(PAGELENTH);
- }
- offsetHeight = getOffsetHeight();
-
- final int desiredWidth = IFilterSelect.this.getOffsetWidth();
- int naturalMenuWidth = DOM.getElementPropertyInt(DOM
- .getFirstChild(menu.getElement()), "offsetWidth");
- if (naturalMenuWidth < desiredWidth) {
- menu.setWidth(desiredWidth + "px");
- DOM.setStyleAttribute(DOM.getFirstChild(menu.getElement()),
- "width", "100%");
- naturalMenuWidth = desiredWidth;
- }
- if (Util.isIE()) {
- DOM.setStyleAttribute(getElement(), "width", naturalMenuWidth
- + "px");
- }
-
- if (offsetHeight + getPopupTop() > Window.getClientHeight()
- + Window.getScrollTop()) {
- // popup on top of input instead
- top = getPopupTop() - offsetHeight
- - IFilterSelect.this.getOffsetHeight();
- if (top < 0) {
- top = 0;
- }
- } else {
- top = getPopupTop();
- }
-
- // fetch real width (mac FF bugs here due GWT popups overflow:auto )
- offsetWidth = DOM.getElementPropertyInt(DOM.getFirstChild(menu
- .getElement()), "offsetWidth");
- if (offsetWidth + getPopupLeft() > Window.getClientWidth()
- + Window.getScrollLeft()) {
- left = IFilterSelect.this.getAbsoluteLeft()
- + IFilterSelect.this.getOffsetWidth()
- + Window.getScrollLeft() - offsetWidth;
- if (left < 0) {
- left = 0;
- }
- } else {
- left = getPopupLeft();
- }
- setPopupPosition(left, top);
-
- }
-
- /**
- * @return true if popup was just closed
- */
- public boolean isJustClosed() {
- final long now = (new Date()).getTime();
- return (lastAutoClosed > 0 && (now - lastAutoClosed) < 200);
- }
-
- public void onPopupClosed(PopupPanel sender, boolean autoClosed) {
- if (autoClosed) {
- lastAutoClosed = (new Date()).getTime();
- }
- }
-
- }
-
- public class SuggestionMenu extends MenuBar {
-
- SuggestionMenu() {
- super(true);
- setStyleName(CLASSNAME + "-suggestmenu");
- }
-
- /**
- * Fixes menus height to use same space as full page would use. Needed
- * to avoid height changes when quickly "scrolling" to last page
- */
- public void fixHeightTo(int pagelenth) {
- if (currentSuggestions.size() > 0) {
- final int pixels = pagelenth * (getOffsetHeight() - 2)
- / currentSuggestions.size();
- setHeight((pixels + 2) + "px");
- }
- }
-
- public void setSuggestions(Collection suggestions) {
- clearItems();
- final Iterator it = suggestions.iterator();
- while (it.hasNext()) {
- final FilterSelectSuggestion s = (FilterSelectSuggestion) it
- .next();
- final MenuItem mi = new MenuItem(s.getDisplayString(), true, s);
- this.addItem(mi);
- if (s == currentSuggestion) {
- selectItem(mi);
- }
- }
- }
-
- public void doSelectedItemAction() {
- final MenuItem item = getSelectedItem();
- final String enteredItemValue = tb.getText();
- // check for exact match in menu
- int p = getItems().size();
- if (p > 0) {
- for (int i = 0; i < p; i++) {
- final MenuItem potentialExactMatch = (MenuItem) getItems()
- .get(i);
- if (potentialExactMatch.getText().equals(enteredItemValue)) {
- selectItem(potentialExactMatch);
- doItemAction(potentialExactMatch, true);
- suggestionPopup.hide();
- return;
- }
- }
- }
- if (allowNewItem) {
-
- if (!enteredItemValue.equals(emptyText)) {
- client.updateVariable(paintableId, "newitem",
- enteredItemValue, immediate);
- }
- } else if (item != null
- && item.getText().toLowerCase().startsWith(
- lastFilter.toLowerCase())) {
- doItemAction(item, true);
- } else {
- if (currentSuggestion != null) {
- String text = currentSuggestion.getReplacementString();
- tb.setText((text.equals("") ? emptyText : text));
- // TODO add/remove class CLASSNAME_EMPTY
- selectedOptionKey = currentSuggestion.key;
- } else {
- tb.setText(emptyText);
- // TODO add class CLASSNAME_EMPTY
- selectedOptionKey = null;
- }
- }
- suggestionPopup.hide();
- }
- }
-
- public static final int FILTERINGMODE_OFF = 0;
- public static final int FILTERINGMODE_STARTSWITH = 1;
- public static final int FILTERINGMODE_CONTAINS = 2;
-
- private static final String CLASSNAME = "i-filterselect";
-
- public static final int PAGELENTH = 10;
-
- private final FlowPanel panel = new FlowPanel();
-
- private final TextBox tb = new TextBox();
-
- private final SuggestionPopup suggestionPopup = new SuggestionPopup();
-
- private final HTML popupOpener = new HTML("");
-
- private final Image selectedItemIcon = new Image();
-
- private ApplicationConnection client;
-
- private String paintableId;
-
- private int currentPage;
-
- private final Collection currentSuggestions = new ArrayList();
-
- private boolean immediate;
-
- private String selectedOptionKey;
-
- private boolean filtering = false;
-
- private String lastFilter = "";
-
- private FilterSelectSuggestion currentSuggestion;
-
- private int totalMatches;
- private boolean allowNewItem;
- private boolean nullSelectionAllowed;
- private boolean enabled;
-
- // shown in unfocused empty field, disappears on focus (e.g "Search here")
- private String emptyText = "";
- private static final String CLASSNAME_EMPTY = "empty";
- private static final String ATTR_EMPTYTEXT = "emptytext";
-
- public IFilterSelect() {
- selectedItemIcon.setVisible(false);
- panel.add(selectedItemIcon);
- panel.add(tb);
- panel.add(popupOpener);
- initWidget(panel);
- setStyleName(CLASSNAME);
- tb.addKeyboardListener(this);
- tb.setStyleName(CLASSNAME + "-input");
- tb.addFocusListener(this);
- popupOpener.setStyleName(CLASSNAME + "-button");
- popupOpener.addClickListener(this);
- }
-
- public boolean hasNextPage() {
- if (totalMatches > (currentPage + 1) * PAGELENTH) {
- return true;
- } else {
- return false;
- }
- }
-
- public void filterOptions(int page) {
- filterOptions(page, tb.getText());
- }
-
- public void filterOptions(int page, String filter) {
- if (filter.equals(lastFilter) && currentPage == page) {
- if (!suggestionPopup.isAttached()) {
- suggestionPopup.showSuggestions(currentSuggestions,
- currentPage, totalMatches);
- }
- return;
- }
- if (!filter.equals(lastFilter)) {
- // we are on subsequent page and text has changed -> reset page
- if ("".equals(filter)) {
- // let server decide
- page = -1;
- } else {
- page = 0;
- }
- }
-
- filtering = true;
- client.updateVariable(paintableId, "filter", filter, false);
- client.updateVariable(paintableId, "page", page, true);
- lastFilter = filter;
- currentPage = page;
- }
-
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- paintableId = uidl.getId();
- this.client = client;
-
- if (uidl.hasAttribute("disabled") || uidl.hasAttribute("readonly")) {
- tb.setEnabled(false);
- enabled = false;
- } else {
- tb.setEnabled(true);
- enabled = true;
- }
-
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- immediate = uidl.hasAttribute("immediate");
-
- nullSelectionAllowed = uidl.hasAttribute("nullselect");
-
- currentPage = uidl.getIntVariable("page");
-
- if (uidl.hasAttribute(ATTR_EMPTYTEXT)) {
- // "emptytext" changed from server
- emptyText = uidl.getStringAttribute(ATTR_EMPTYTEXT);
- }
-
- suggestionPopup.setPagingEnabled(true);
-
- allowNewItem = uidl.hasAttribute("allownewitem");
-
- currentSuggestions.clear();
- final UIDL options = uidl.getChildUIDL(0);
- totalMatches = uidl.getIntAttribute("totalMatches");
-
- String captions = emptyText;
-
- for (final Iterator i = options.getChildIterator(); i.hasNext();) {
- final UIDL optionUidl = (UIDL) i.next();
- final FilterSelectSuggestion suggestion = new FilterSelectSuggestion(
- optionUidl);
- currentSuggestions.add(suggestion);
- if (optionUidl.hasAttribute("selected")) {
- if (!filtering) {
- tb.setText(suggestion.getReplacementString());
- }
- currentSuggestion = suggestion;
- }
-
- // Collect captions so we can calculate minimum width for textarea
- if (captions.length() > 0) {
- captions += "|";
- }
- captions += suggestion.getReplacementString();
- }
-
- if (!filtering && uidl.hasVariable("selected")
- && uidl.getStringArrayVariable("selected").length == 0) {
- // select nulled
- tb.setText(emptyText);
- selectedOptionKey = null;
- // TODO add class CLASSNAME_EMPTY
- }
-
- if (filtering
- && lastFilter.toLowerCase().equals(
- uidl.getStringVariable("filter"))) {
- suggestionPopup.showSuggestions(currentSuggestions, currentPage,
- totalMatches);
- filtering = false;
- }
-
- // Calculate minumum textarea width
- final int minw = minWidth(captions);
- final Element spacer = DOM.createDiv();
- DOM.setStyleAttribute(spacer, "width", minw + "px");
- DOM.setStyleAttribute(spacer, "height", "0");
- DOM.setStyleAttribute(spacer, "overflow", "hidden");
- DOM.appendChild(panel.getElement(), spacer);
-
- }
-
- public void onSuggestionSelected(FilterSelectSuggestion suggestion) {
- currentSuggestion = suggestion;
- String newKey;
- if (suggestion.key.equals("")) {
- // "nullselection"
- newKey = "";
- } else {
- // normal selection
- newKey = String.valueOf(suggestion.getOptionKey());
- }
- String text = suggestion.getReplacementString();
- tb.setText(text.equals("") ? emptyText : text);
- // TODO add/remove class CLASSNAME_EMPTY
- setSelectedItemIcon(suggestion.getIconUri());
- if (!newKey.equals(selectedOptionKey)) {
- selectedOptionKey = newKey;
- client.updateVariable(paintableId, "selected",
- new String[] { selectedOptionKey }, immediate);
- // currentPage = -1; // forget the page
- }
- suggestionPopup.hide();
- }
-
- private void setSelectedItemIcon(String iconUri) {
- if (iconUri == null) {
- selectedItemIcon.setVisible(false);
- } else {
- selectedItemIcon.setUrl(iconUri);
- selectedItemIcon.setVisible(true);
- }
- }
-
- public void onKeyDown(Widget sender, char keyCode, int modifiers) {
- if (enabled && suggestionPopup.isAttached()) {
- switch (keyCode) {
- case KeyboardListener.KEY_DOWN:
- suggestionPopup.selectNextItem();
- DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
- break;
- case KeyboardListener.KEY_UP:
- suggestionPopup.selectPrevItem();
- DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
- break;
- case KeyboardListener.KEY_PAGEDOWN:
- if (hasNextPage()) {
- filterOptions(currentPage + 1, lastFilter);
- }
- break;
- case KeyboardListener.KEY_PAGEUP:
- if (currentPage > 0) {
- filterOptions(currentPage - 1, lastFilter);
- }
- break;
- case KeyboardListener.KEY_ENTER:
- case KeyboardListener.KEY_TAB:
- suggestionPopup.menu.doSelectedItemAction();
- break;
- }
- }
- }
-
- public void onKeyPress(Widget sender, char keyCode, int modifiers) {
-
- }
-
- public void onKeyUp(Widget sender, char keyCode, int modifiers) {
- if (enabled) {
- switch (keyCode) {
- case KeyboardListener.KEY_ENTER:
- case KeyboardListener.KEY_TAB:
- ; // NOP
- break;
- case KeyboardListener.KEY_DOWN:
- case KeyboardListener.KEY_UP:
- case KeyboardListener.KEY_PAGEDOWN:
- case KeyboardListener.KEY_PAGEUP:
- if (suggestionPopup.isAttached()) {
- break;
- } else {
- // open popup as from gadget
- filterOptions(-1, "");
- lastFilter = "";
- tb.selectAll();
- break;
- }
- default:
- filterOptions(currentPage);
- break;
- }
- }
- }
-
- /**
- * Listener for popupopener
- */
- public void onClick(Widget sender) {
- if (enabled) {
- // ask suggestionPopup if it was just closed, we are using GWT
- // Popup's
- // auto close feature
- if (!suggestionPopup.isJustClosed()) {
- filterOptions(-1, "");
- lastFilter = "";
- }
- DOM.eventPreventDefault(DOM.eventGetCurrentEvent());
- tb.setFocus(true);
- tb.selectAll();
-
- }
- }
-
- /*
- * Calculate minumum width for FilterSelect textarea
- */
- private native int minWidth(String captions)
- /*-{
- if(!captions || captions.length <= 0)
- return 0;
- captions = captions.split("|");
- var d = $wnd.document.createElement("div");
- var html = "";
- for(var i=0; i < captions.length; i++) {
- html += "<div>" + captions[i] + "</div>";
- // TODO apply same CSS classname as in suggestionmenu
- }
- d.style.position = "absolute";
- d.style.top = "0";
- d.style.left = "0";
- d.style.visibility = "hidden";
- d.innerHTML = html;
- $wnd.document.body.appendChild(d);
- var w = d.offsetWidth;
- $wnd.document.body.removeChild(d);
- return w;
- }-*/;
-
- public void onFocus(Widget sender) {
- if (emptyText.equals(tb.getText())) {
- tb.setText("");
- // TODO remove class CLASSNAME_EMPTY
- }
- }
-
- public void onLostFocus(Widget sender) {
- if (suggestionPopup.isJustClosed()) {
- suggestionPopup.menu.doSelectedItemAction();
- }
- if ("".equals(tb.getText())) {
- tb.setText(emptyText);
- // TODO add CLASSNAME_EMPTY
- }
- }
-
- public void focus() {
- tb.setFocus(true);
- }
- }
|