Contrib: Auto-completion textboxes

43 views
Skip to first unread message

Simp

unread,
May 19, 2006, 5:09:34 PM5/19/06
to Google Web Toolkit
As there are none yet I started to write some auto completing
textboxes. Doesn't work quite right now in every browser plus I have no
clue yet how to put those in a more meaningful package and still be
able to use it in my test app. Bear with me, some classes ;)

CompletionItems.java:

package de.aaworks.SimpleTest.client;

public interface CompletionItems {
/**
* Returns an array of all completion items matching
* @param match The user-entered text all compleition items have to
match
* @return Array of strings
*/
public String[] getCompletionItems(String match);
}

Simp

unread,
May 19, 2006, 5:14:50 PM5/19/06
to Google Web Toolkit
AutoCompleteTextBox.java:

package de.aaworks.SimpleTest.client;

import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class AutoCompleteTextBox extends TextBox implements
KeyboardListener,
ChangeListener, ClickListener {

protected PopupPanel choicesPopup = new PopupPanel(true);
protected ListBox choices = new ListBox();
protected CompletionItems items = new SimpleAutoCompletionItems(new
String[]{});
protected boolean popupAdded = false;

/**
* Default Constructor
*
*/
public AutoCompleteTextBox()
{
super();
this.addKeyboardListener(this);
choices.addChangeListener(this);
choices.addClickListener(this);

choicesPopup.add(choices);
}

/**
* Sets an "algorithm" returning completion items
* You can define your own way how the textbox retrieves
autocompletion items
* by implementing the CompletionItems interface and setting the
according object
* @see SimpleAutoCompletionItem
* @param items CompletionItem implementation
*/
public void setCompletionItems(CompletionItems items)
{
this.items = items;
}

/**
* Returns the used CompletionItems object
* @return CompletionItems implementation
*/
public CompletionItems getCompletionItems()
{
return this.items;
}

/**
* Not used at all
*/
public void onKeyDown(Widget arg0, char arg1, int arg2) {
}

/**
* Not used at all
*/
public void onKeyPress(Widget arg0, char arg1, int arg2) {
}

/**
* A key was released, start autocompletion
*/
public void onKeyUp(Widget arg0, char arg1, int arg2) {
if(arg1 == KEY_DOWN)
{
int selectedIndex = choices.getSelectedIndex();
selectedIndex++;
if(selectedIndex > choices.getItemCount())
{
selectedIndex = 0;
}
choices.setSelectedIndex(selectedIndex);

return;
}

if(arg1 == KEY_UP)
{
int selectedIndex = choices.getSelectedIndex();
selectedIndex--;
if(selectedIndex < 0)
{
selectedIndex = choices.getItemCount();
}
choices.setSelectedIndex(selectedIndex);

return;
}

if(arg1 == KEY_ENTER)
{
complete();
}

if(arg1 == KEY_ESCAPE)
{
choices.clear();
choicesPopup.hide();
}

String text = this.getText();
String[] matches = new String[]{};
if(text.length() > 0)
{
matches = items.getCompletionItems(text);
}

if(matches.length > 0)
{
choices.clear();

for(int i = 0; i < matches.length; i++)
{
choices.addItem((String) matches[i]);
}

// if there is only one match and it is what is in the
// text field anyways there is no need to show autocompletion
if(matches.length == 1 && matches[0].compareTo(text) == 0)
{
choicesPopup.hide();
} else {
choices.setSelectedIndex(0);
choices.setVisibleItemCount(matches.length + 1);

if(!popupAdded)
{
RootPanel.get().add(choicesPopup);
popupAdded = true;
}
choicesPopup.show();
choicesPopup.setPopupPosition(this.getAbsoluteLeft(),
this.getAbsoluteTop() + this.getOffsetHeight());
//choicesPopup.setWidth(this.getOffsetWidth() + "px");
choices.setWidth(this.getOffsetWidth() + "px");
}

} else {
choicesPopup.hide();
}
}

/**
* A mouseclick in the list of items
*/
public void onChange(Widget arg0) {
complete();
}
public void onClick(Widget arg0) {
complete();
}

// add selected item to textbox
protected void complete()
{
if(choices.getItemCount() > 0)
{
this.setText(choices.getItemText(choices.getSelectedIndex()));
}

choices.clear();
choicesPopup.hide();
}
}

Simp

unread,
May 19, 2006, 5:14:21 PM5/19/06
to Google Web Toolkit
SimpleAutoCompletionItems.java:

package de.aaworks.SimpleTest.client;

import java.util.ArrayList;

public class SimpleAutoCompletionItems implements CompletionItems {
private String[] completions;

public SimpleAutoCompletionItems(String[] items)
{
completions = items;
}

public String[] getCompletionItems(String match) {
ArrayList matches = new ArrayList();
for (int i = 0; i < completions.length; i++) {
if (completions[i].toLowerCase().startsWith(match.toLowerCase())) {
matches.add(completions[i]);
}
}
String[] returnMatches = new String[matches.size()];
for(int i = 0; i < matches.size(); i++)
{
returnMatches[i] = (String)matches.get(i);
}

return returnMatches;
}
}

Simp

unread,
May 19, 2006, 5:44:50 PM5/19/06
to Google Web Toolkit
Seems like my last post diappeared... reposting it..


Finally, how to use it.

Wel, I've taylored it the way it is so everyone can implement the
Interface CompletionItems and get autocompletion items from wherever
they want (RPC calls and thelike). For simple autocompletion with
predefined items one can use the given sample implementation. Here's
some example:

final AutoCompleteTextBox box = new AutoCompleteTextBox();
box.setCompletionItems(new SimpleAutoCompletionItems(
new String[]{ "apple", "ape", "anything", "else"}));

Finally: the code is under public domain - feel free to use/change it
as you want. I'd be happy about hints on packaging and bugfixes. ;)

Simp

unread,
May 19, 2006, 5:18:16 PM5/19/06
to Google Web Toolkit
Finally, how to use ist.

mohan

unread,
May 19, 2006, 6:51:05 PM5/19/06
to Google Web Toolkit


Hi Simp,
Cool. It works vey well.

Regards,
Mohan

Simp

unread,
May 24, 2006, 3:34:03 PM5/24/06
to Google Web Toolkit
Okay, I just packaged another version with less bugs plus support for
textareas.
Sources can be requested by mail (I'm too lazy to enter those classes
in here again ;) ) and probably will be on the
gwt.components.googlepages.com website soon.

gwt.com...@gmail.com

unread,
May 27, 2006, 5:40:06 PM5/27/06
to Google Web Toolkit
Updated version is here: http://gwt.components.googlepages.com/

Thank you, Oliver.

Ollie

unread,
Jun 3, 2006, 2:11:22 PM6/3/06
to Google Web Toolkit

gwt.com...@gmail.com wrote:
> Updated version is here: http://gwt.components.googlepages.com/
>
> Thank you, Oliver.

Hello, great peace of code, very interresting.

How do you make it RPC though ? Since it must use Asynchronous service,
I don't really know how to implement the interface.

I have so far, something looking like :

public class RemoteAutoCompletionItems implements CompletionItems {

private AutoCompleteBackEndServiceAsync service;

private ServiceDefTarget endpoint;

public RemoteAutoCompletionItems (String entryEndPoint) {
service = (AutoCompleteBackEndServiceAsync)
GWT.create(AutoCompleteBackEndService .class);
endpoint = (ServiceDefTarget) service;
endpoint.setServiceEntryPoint( entryEndPoint );
}

public String[] getCompletionItems(String match) {
AsyncCallback call = new AsyncCallback( ) {

public void onFailure(Throwable caught) {
// TODO Auto-generated method stub

}

public void onSuccess(Object result) {

}

};

service.getAutoComplete( match, call);

}
}

Simp

unread,
Jun 3, 2006, 2:57:35 PM6/3/06
to Google Web Toolkit
Actually that's a bit of a problem I struggle with right now while
working on further refined versions.

You currently are able to do something like that:


public class RemoteAutoCompletionItems implements CompletionItems {

private String[] items;
private MyServletAsync serv;
private AsyncCallback callback = new AsyncCallback() {

public void onSuccess(Object result) {
items = (String[]) result;
}

public void onFailure(Throwable caught) {
}
};

public RemoteAutoCompletionItems (String url) {
serv = (MyServletAsync) GWT.create(MyServlet.class);
ServiceDefTarget point = (ServiceDefTarget) serv;
point.setServiceEntryPoint(url);

}

public String[] getCompletionItems(String match) {
serv.getHTML2(2, callback);
if(items != null) return items;
return new String[0];
}
}

Obviously that's not perfect as it always lags behind what the user
entered.
The next version of the code actually attacks this problem by allowing
async updates of the list of items from the callback by having a
updateItems() method in the textbox callable by completionitems.

I'd love to hear input. :)

Olli

Ollie

unread,
Jun 5, 2006, 4:37:54 AM6/5/06
to Google Web Toolkit
Hey I actually managed to use async, by changing slightly your
component :-)

I have done something like you, I allow the completion items to update
the list of items with a method onMatch(), it was just a matter of
little refactoring.

Thanks

Olivier

/**
* A key was released, start autocompletion
*/
public void onKeyUp(Widget arg0, char arg1, int arg2) {

if (arg1 == KEY_DOWN) {


int selectedIndex = choices.getSelectedIndex();
selectedIndex++;

if (selectedIndex > choices.getItemCount()) {
selectedIndex = 0;
}
choices.setSelectedIndex(selectedIndex);

return;
}

if (arg1 == KEY_UP) {


int selectedIndex = choices.getSelectedIndex();
selectedIndex--;

if (selectedIndex < 0) {
selectedIndex = choices.getItemCount();
}
choices.setSelectedIndex(selectedIndex);

return;
}

if (arg1 == KEY_ENTER) {
if (visible) {
complete();
}

return;
}


if (arg1 == KEY_ESCAPE) {
choices.clear();
choicesPopup.hide();
visible = false;

return;
}

String text = this.getText();
matches = new String[] {};
if (text.length() > 0) {
items.getCompletionItems(text,this);
} else {
onMatch(text);
}


}


public void setMatches(String[] matches) {
this.matches = matches;
}

// use for Asynchronous Match
public void onMatch(String text) {
if (matches.length > 0) {
choices.clear();

for (int i = 0; i < matches.length; i++) {
choices.addItem((String) matches[i]);
}

// if there is only one match and it is what is in the
// text field anyways there is no need to show autocompletion

if (matches.length == 1 && matches[0].compareTo(text) == 0) {


choicesPopup.hide();
} else {
choices.setSelectedIndex(0);
choices.setVisibleItemCount(matches.length + 1);

if (!popupAdded) {
RootPanel.get().add(choicesPopup);
popupAdded = true;
}
choicesPopup.show();

visible = true;
choicesPopup.setPopupPosition(this.getAbsoluteLeft(), this
.getAbsoluteTop()
+ this.getOffsetHeight());
// choicesPopup.setWidth(this.getOffsetWidth() + "px");
choices.setWidth(this.getOffsetWidth() + "px");
}

} else {
visible = false;
choicesPopup.hide();
}
}

Ollie

unread,
Jun 5, 2006, 4:43:55 AM6/5/06
to Google Web Toolkit
I also have a MatchRequiring interface for every component that will
require matching :

package com.gwt.components.client;

public interface MatchesRequiring {

public void onMatch(String text);

public void setMatches(String[] matches);

}

And the CompletionItems changes slightly, to be able to access the
widget :

/*Auto-Completion Textbox for GWTCopyright (C) 2006 Oliver Albers
http://gwt.components.googlepages.com/This library is free software;
you can redistribute it and/ormodify it under the terms of the GNU
Lesser General PublicLicense as published by the Free Software
Foundation; eitherversion 2.1 of the License, or (at your option) any
later version.This library is distributed in the hope that it will be
useful,but WITHOUT ANY WARRANTY; without even the implied warranty
ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNULesser General Public License for more details.You should have
received a copy of the GNU Lesser General PublicLicense along with this
library; if not, write to the Free SoftwareFoundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/package
com.gwt.components.client;

public interface CompletionItems {
/**
* Returns an array of all completion items matching
*

* @param match
* The user-entered text all compleition items have to


match
* @return Array of strings
*/

public void getCompletionItems(String match, MatchesRequiring
widget);
}


The code in RemoteAutoCompletion look like this :

public class RemoteAutoCompletionItems implements CompletionItems {

private AutoCompleteBackEndServiceAsync service;

private ServiceDefTarget endpoint;

public RemoteAutoCompletionItems (String entryEndPoint) {
service = (AutoCompleteBackEndServiceAsync)
GWT.create(AutoCompleteBackEndService .class);
endpoint = (ServiceDefTarget) service;
endpoint.setServiceEntryPoint( entryEndPoint );
}

public void getCompletionItems(final String match, final
MatchesRequiring widget) {

AsyncCallback call = new AsyncCallback( ) {

public void onFailure(Throwable caught) {

}

public void onSuccess(Object result) {
widget.setMatches( (String[]) result);
widget.onMatch( match );
}

};

service.getAutoComplete( match, call);
}

}

Simp

unread,
Jun 5, 2006, 8:09:15 AM6/5/06
to Google Web Toolkit
Yes, that's pretty much how I was planning it to do. Thank's for the
patch.
How's it working out for you now?

krishnam...@gmail.com

unread,
Jun 6, 2006, 7:08:54 AM6/6/06
to Google Web Toolkit
hi i was trying out the Autocompletetextbox and i am finding a bug. iam
running it in the hosted mode using firefix browser. everything is
working fine except that the first element in the listbox is not
getting selected when clicked using mouse.

Ollie

unread,
Jun 6, 2006, 7:14:02 AM6/6/06
to Google Web Toolkit
It's working fine, except that when I delete all the characters in the
textbox, the AutoComplete box does not disapear, but stay populated
with the last values. I did not look deeply into this issue, but what I
found strange, is that it worked correctly with the Java version (and
google browser), but did not work with the javascript version. So it
could be my mistake, or a nasty bug in the google compilator.

Olivier

Dan

unread,
Jun 6, 2006, 10:02:49 AM6/6/06
to Google Web Toolkit
I have the same bug as kirshnamoorthy, clicking the first element
results in nothing happening. Nothing huge, but may annoy some users.

kris

unread,
Jun 10, 2006, 5:02:51 PM6/10/06
to Google Web Toolkit
Dan wrote:
> I have the same bug as kirshnamoorthy, clicking the first element
> results in nothing happening. Nothing huge, but may annoy some users.

an almost workaround is to comment out the automatic selection of the
first element of the list in object 'choices'. see:

// if there is only one match and it is what is in the
// text field anyways there is no need to show autocompletion

if(matches.length == 1 && matches[0].compareTo(text) == 0)
{
choicesPopup.hide();
} else {
//choices.setSelectedIndex(0);
choices.setVisibleItemCount(matches.length + 1);

I see only change events on that choices-popup, and there is no change
if you click on an already selected item !

adding a ClickListener did not solve the behavior. a proper fix would
be to use a MouseListener. hope that helps.

PS:
I also changed
choices.setVisibleItemCount(matches.length + 1);
to something like
choices.setVisibleItemCount(matches.length > MAX_ITEMS?
MAX_ITEMS:
matches.length);
cause I a have long lists.

and lots of thanx for the code so, it was very helpful for me !!

Simp

unread,
Jun 10, 2006, 7:34:31 PM6/10/06
to Google Web Toolkit
Okay, I see your point. I'll try switching to a MouseListener as soon
as possible.

As some of you guys actually seem to use the code I set up a subversion
repository (publicle accessible) at http://www.aa-works.de/svn/
Also there is a Trac set up for bug reports etc:
http://www.aa-works.de/trac/

If somebody is interested I'd be interested in handing out write access
to the code. ;)

rusty

unread,
Jun 13, 2006, 3:27:48 AM6/13/06
to Google Web Toolkit
Hi,

I've been using this control for a little while now, and overall it's
great. I just noticed something though: in Safari when you use the down
arrow, the control skips over one of the matches (eg: it goes down 2
rows instead of 1). I've tried it in IE & Firefox on the PC and Firefox
and Safari on the mac. This only seems to happen in Safari.

Any ideas what might be causing this behaviour?

Rusty

Simp

unread,
Jun 13, 2006, 6:07:32 AM6/13/06
to Google Web Toolkit
Hi Rusty,

> This only seems to happen in Safari.

Too bad. I don't have a Mac and can't debug it then.

> Any ideas what might be causing this behaviour?

Maybe Safari generated two Keyboard events, but that's only a guess.
Could you add a Window.alert() or something like that to see if
onKeyUp is called twice?

AggyLlama

unread,
Jun 21, 2006, 4:03:51 PM6/21/06
to Google Web Toolkit
I've noticed that if the text entered is longer than is allowed in the
textbox, the completion list starts being offset to the left of the
textbox. This happens in the hosted window as well as in IE, though in
Firefox it seems to work fine.
I'm assuming this is a problem with the getAbsoluteLeft method that is
somehow returning incorrect values. Any ideas for a workaround?

Thanks

AggyLlama

unread,
Jun 21, 2006, 4:05:31 PM6/21/06
to Google Web Toolkit
Minor Correction: What I meant was that the text entered is longer than
the display size of the text box, not longer than the allowed length...

meta-generic

unread,
Jun 23, 2006, 2:03:28 PM6/23/06
to Google Web Toolkit
I've spent a lot of time over the last few days getting
AutoCompleteTextBox to do what I want it to, and in the process made a
lot of modifications. Things I've done to it:

1. ListBox now responds to click events. Uses onBrowserEvent since a
ListBox bug prevents onClick from being called.
2. onKeyUp was refactored for better readability.
3. Completion occurs on tab as well as enter.
4. The onChange event handler is no longer needed.
5. Bug fixed: Pressing the up or down keys could cause the list
selection to go out of bounds.
6. Better matching logic that keeps invalid choices from being
displayed, even if an async call is delayed or fails. Assumes simple
case-insensitive "starts with" matching.
7. Generic async RPC mechanism.
8. Other minor tweaks.

New source code in the next post.

meta-generic

unread,
Jun 23, 2006, 2:08:14 PM6/23/06
to Google Web Toolkit
--------------------------------------------------------------
AutoCompleteTextBoxAsync.java
--------------------------------------------------------------

package com.gwt.components.client;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;


import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

public class AutoCompleteTextBoxAsync extends TextBox
implements KeyboardListener {

protected CompletionItemsAsync items = null;


protected boolean popupAdded = false;

protected boolean visible = false;


protected PopupPanel choicesPopup = new PopupPanel(true);

protected ListBox choices = new ListBox() {
public void onBrowserEvent(Event event) {
if (Event.ONCLICK == DOM.eventGetType(event)) {
complete();
}
}
};

/**
* Default Constructor
*/
public AutoCompleteTextBoxAsync()
{
super();
this.addKeyboardListener(this);
choices.sinkEvents(Event.ONCLICK);
this.setStyleName("AutoCompleteTextBox");

choicesPopup.add(choices);
choicesPopup.addStyleName("AutoCompleteChoices");

choices.setStyleName("list");
}

/**
* Sets an "algorithm" returning completion items
* You can define your own way how the textbox retrieves
autocompletion items
* by implementing the CompletionItems interface and setting the
according object
* @see SimpleAutoCompletionItem
* @param items CompletionItem implementation
*/

public void setCompletionItems(CompletionItemsAsync items)
{
this.items = items;
}

/**
* Returns the used CompletionItems object
* @return CompletionItems implementation
*/

public CompletionItemsAsync getCompletionItems()
{
return this.items;
}

/**
* Handle events that happen when keys are pressed.
*/
public void onKeyDown(Widget arg0, char arg1, int arg2) {
if(arg1 == KEY_ENTER)
{
enterKey(arg0, arg1, arg2);
}
else if(arg1 == KEY_TAB)
{
tabKey(arg0, arg1, arg2);
}
else if(arg1 == KEY_DOWN)
{
downKey(arg0, arg1, arg2);
}
else if(arg1 == KEY_UP)
{
upKey(arg0, arg1, arg2);
}
else if(arg1 == KEY_ESCAPE)
{
escapeKey(arg0, arg1, arg2);
}
}

/**
* Not used at all
*/

public void onKeyPress(Widget arg0, char arg1, int arg2) {
}

/**
* Handle events that happen when keys are released.


*/
public void onKeyUp(Widget arg0, char arg1, int arg2) {

switch(arg1) {
case KEY_ALT:
case KEY_CTRL:
case KEY_DOWN:
case KEY_END:
case KEY_ENTER:
case KEY_ESCAPE:
case KEY_HOME:
case KEY_LEFT:
case KEY_PAGEDOWN:
case KEY_PAGEUP:
case KEY_RIGHT:
case KEY_SHIFT:
case KEY_TAB:
case KEY_UP:
break;
default:
otherKey(arg0, arg1, arg2);
break;
}
}

// The down key was pressed.
protected void downKey(Widget arg0, char arg1, int arg2) {


int selectedIndex = choices.getSelectedIndex();
selectedIndex++;

if (selectedIndex >= choices.getItemCount())
{
selectedIndex = 0;
}
choices.setSelectedIndex(selectedIndex);
}

// The up key was pressed.
protected void upKey(Widget arg0, char arg1, int arg2) {


int selectedIndex = choices.getSelectedIndex();
selectedIndex--;

if(selectedIndex < 0)
{
selectedIndex = choices.getItemCount() - 1;
}
choices.setSelectedIndex(selectedIndex);
}

// The enter key was pressed.
protected void enterKey(Widget arg0, char arg1, int arg2) {
complete();
}

// The tab key was pressed.
protected void tabKey(Widget arg0, char arg1, int arg2) {
complete();
}

// The escape key was pressed.
protected void escapeKey(Widget arg0, char arg1, int arg2) {
choices.clear();
choicesPopup.hide();
this.visible = false;
}

// Any other non-special key was pressed.
protected void otherKey(Widget arg0, char arg1, int arg2) {
// Update the existing choices in the list box to reflect the
user's entry.
updateChoices(this.getText());

// If any text was entered, start an async callback.
if (this.getText().length() > 0 && items != null) {
items.getCompletionItems(this.getText(), new
CompletionItemsAsyncReturn() {
public void itemReturn(String[] matches) {
updateChoices(matches, getText());
}
});
}
}

// Hides/shows the choice box as needed.
// Assumes all choices are currently valid.
protected void hideChoicesIfNeeded(String text) {
// Hide the list box under any of these conditions:
// - the text box is empty
// - there are no matching choices
// - there is only one choice that exactly matches the text box
entry
// Show the list box under any other condition.
if (0 == text.length() || 0 == choices.getItemCount() ||
(1 == choices.getItemCount() &&
choices.getItemText(0).equals(text))) {


choices.clear();
choicesPopup.hide();
visible = false;

} else {
choices.setSelectedIndex(0);
choices.setVisibleItemCount(choices.getItemCount() + 1);

if(!popupAdded) {


RootPanel.get().add(choicesPopup);
popupAdded = true;
}
choicesPopup.show();
visible = true;
choicesPopup.setPopupPosition(this.getAbsoluteLeft(),
this.getAbsoluteTop() + this.getOffsetHeight());

choices.setWidth(this.getOffsetWidth() + "px");
}
}

// Removes all items in the choices menu that do not start with the
specified text.
protected void updateChoices(String text) {
int i = 0;
while (i < choices.getItemCount()) {
if
(choices.getItemText(i).toLowerCase().startsWith(text.toLowerCase())) {
++i;
} else {
choices.removeItem(i);
}
}
hideChoicesIfNeeded(text);
}

// Update the choices menu using the provided matches and entered
text.
protected void updateChoices(String[] matches, String text) {
choices.clear();
for(int i = 0; i < matches.length; i++)
{
choices.addItem((String) matches[i]);
}
updateChoices(text);
}

// add selected item to textbox
protected void complete()
{

if(this.visible && choices.getItemCount() > 0)
{
this.setText(choices.getItemText(choices.getSelectedIndex()));
}
choices.clear();
choicesPopup.hide();
this.visible = false;
}
}


--------------------------------------------------------------
CompletionItemsAsync.java
--------------------------------------------------------------

package com.gwt.components.client;

public interface CompletionItemsAsync {
/**
* Makes a call to find all completion items matching.
* @param match The user-entered text all completion items have
to match
* @param asyncReturn The object invoked when the async call
returns correctly


*/
public void getCompletionItems(String match,

CompletionItemsAsyncReturn asyncReturn);
}


--------------------------------------------------------------
CompletionItemsAsyncReturn.java
--------------------------------------------------------------

package com.gwt.components.client;

public interface CompletionItemsAsyncReturn {
/**
* Handles an array of items. Called by
<code>CompletionItemsAsync.getCompletionItems</code>
* @param items The array of compleition items
*/
public void itemReturn(String[] items);
}

Reply all
Reply to author
Forward
0 new messages