You can't just subclass MWSO, but it's declared final.
You cannot just copy (and repackage) MultiWordSuggestOracle and muck
with it, because it uses the PrefixTree class, which is package-scope
only. If you try to also copy PrefixTree to fix that, you've got to
change all the package nomenclature in the JSNI (and even after I
tried that I still got JavaScript exceptions and gave up.) I was
eventually able to make my own MWSO subclass but it required copying a
dozen source files just to change a few lines of code.
Has anyone found a reasonably simple way to create their own
SuggestOracle or make a specialization of the MWSO?
Thanks,
Michael
I implemented my StartsWithSuggestOracle to match items that start
with the typed value, case-insensitive. It was fairly
straightforward; the only tricky part was figuring out that the
matching results given to the Response is List<Suggestion> not
List<String>, and that I had to implement my own Suggestion. The full
class implementation is pasted below.
My comparison of the query to all of the choices is just dumb
iteration, but it's fast enough in hosted mode and on FF to suffice,
even with my large and complex list of possible choices (900 bacteria
names that are 50-80 characters long).
For Google, here are my suggestions for simplifying this process:
* There should be a default implementation of Suggest since it seems
likely that most Oracles will use the basic implementation
* A default method for formatting the display string would be useful
so we all don't have to write StringBuffers to chop up and format the
string. Using a CSS style by default instead of the hard-coded
"<strong>" tags would be preferable.
* As mentioned above, a remove() method on SuggestOracle would make
sense.
Michael
package org.jcvi.camera.web.gwt.common.client.ui.suggest;
import org.jcvi.camera.web.gwt.common.client.service.log.Logger;
import com.google.gwt.user.client.ui.SuggestOracle;
import com.google.gwt.user.client.rpc.IsSerializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Implementation of GWT's SuggestOracle that returns matching items
if they start with the specified query string
* (case-insensitive)
*
* @author Michael Press
*/
public class StartsWithSuggestOracle extends SuggestOracle
{
private static Logger _logger =
Logger.getLogger("org.jcvi.camera.web.gwt.common.client.ui.suggest.StartsWithSuggestOracle");
ArrayList items = new ArrayList();
public StartsWithSuggestOracle()
{
}
/**
* Wrapper class that's used for each matching Suggestion
returned.
*/
public static class StartsWithSuggestion implements Suggestion,
IsSerializable
{
private String _value;
private String _displayString;
/**
* Constructor used by RPC.
*/
public StartsWithSuggestion() { }
/**
* Constructor for <code>StartsWithSuggestion</code>.
*/
public StartsWithSuggestion(String value, String
displayString)
{
_value = value;
_displayString = displayString;
}
public String getDisplayString()
{
return _displayString;
}
public Object getValue()
{
return _value;
}
}
/**
* Implementation of the sole abstract method in parent
SuggestOracle. Determines which strings match the
* query string, populates a Response (which contains a
List<StartsWithSuggestion>) and passes it to the supplied
* Callback
*/
public void requestSuggestions(Request request, Callback callback)
{
final List/*<StartsWithSuggestion*/ suggestions =
computeItemsFor(request.getQuery().toLowerCase(), request.getLimit());
Response response = new Response(suggestions);
callback.onSuggestionsReady(request, response);
}
/**
* Decides which strings match the supplied query; in this case,
if the string starts with the query (case-insensitive)
*/
private List computeItemsFor(String query, int limit)
{
ArrayList/*<StartsWithSuggestion>*/ matches = new ArrayList();
for (int i = 0; i < items.size() && matches.size() < limit; i+
+)
if (query.matches(((String) items.get(i)).substring(0,
query.length()).toLowerCase()))
matches.add(getFormattedSuggestion(query, (String)
items.get(i)));
_logger.debug("found " + matches.size() + " matches for query
" + query);
return matches;
}
/**
* Formats the display string that will be shown in the SuggestBox
popup
*/
private StartsWithSuggestion getFormattedSuggestion(String query,
String suggestion)
{
StringBuffer formattedSuggestion = new StringBuffer()
.append("<strong>")
.append(suggestion.substring(0, query.length()))
.append("</strong>")
.append(suggestion.substring(query.length()));
return new StartsWithSuggestion(suggestion,
formattedSuggestion.toString());
}
public void add(String suggestion)
{
items.add(suggestion);
}
public void addAll(Collection collection)
{
_logger.debug("added " + collection.size() + " items to
StartsWithSuggestOracle");
items.addAll(collection);
}
/**
* Specifies that the display string we're returning in the
StartsWithSuggestion is HTML
*/
public boolean isDisplayStringHTML() {
return true;