Auto-Completion Textbox for GWT
package com.java2s.gwt.client; import java.util.ArrayList; import com.google.gwt.user.client.ui.*; import com.google.gwt.core.client.EntryPoint; public class GWTClient implements EntryPoint{ public void onModuleLoad() { final AutoCompleteTextBox box = new AutoCompleteTextBox(); box.setCompletionItems(new SimpleAutoCompletionItems( new String[]{ "apple", "ape", "anything", "else"})); Label zipLabel = new Label("zip"); Grid grid = new Grid(4, 2); grid.setWidget(0, 0, zipLabel); grid.setWidget(0, 1, box); RootPanel.get().add(grid); } } /* Auto-Completion Textbox for GWT Copyright (C) 2006 Oliver Albers http://gwt.components.googlepages.com/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 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 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 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); } /* Auto-Completion Textbox for GWT Copyright (C) 2006 Oliver Albers http://gwt.components.googlepages.com/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 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 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ class AutoCompleteTextBox extends TextBox implements KeyboardListener, ChangeListener { protected PopupPanel choicesPopup = new PopupPanel(true); protected ListBox choices = new ListBox(); protected CompletionItems items = new SimpleAutoCompletionItems(new String[]{}); protected boolean popupAdded = false; protected boolean visible = false; /** * Default Constructor * */ public AutoCompleteTextBox() { super(); this.addKeyboardListener(this); choices.addChangeListener(this); 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(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) { if(visible) { complete(); } return; } if(arg1 == KEY_ESCAPE) { choices.clear(); choicesPopup.hide(); visible = false; return; } 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(); 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(); } } /** * 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(); } } /* Auto-Completion Textbox for GWT Copyright (C) 2006 Oliver Albers http://gwt.components.googlepages.com/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 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 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ class AutoCompleteTextArea extends TextArea implements KeyboardListener, ChangeListener { protected PopupPanel choicesPopup = new PopupPanel(true); protected ListBox choices = new ListBox(); protected CompletionItems items = new SimpleAutoCompletionItems(new String[]{}); protected boolean popupAdded = false; protected String typedText = ""; protected boolean visible = false; protected int posy = -1; /** * Default Constructor * */ public AutoCompleteTextArea() { super(); this.addKeyboardListener(this); choices.addChangeListener(this); this.setStyleName("AutoCompleteTextArea"); 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(CompletionItems items) { this.items = items; } /** * Returns the used CompletionItems object * @return CompletionItems implementation */ public CompletionItems getCompletionItems() { return this.items; } public void onKeyDown(Widget sender, char keyCode, int modifiers) { } public void onKeyPress(Widget sender, char keyCode, int modifiers) { } public void onKeyUp(Widget sender, char keyCode, int modifiers) { if(keyCode == KEY_DOWN) { int selectedIndex = choices.getSelectedIndex(); selectedIndex++; if(selectedIndex > choices.getItemCount()) { selectedIndex = 0; } choices.setSelectedIndex(selectedIndex); return; } if(keyCode == KEY_UP) { int selectedIndex = choices.getSelectedIndex(); selectedIndex--; if(selectedIndex < 0) { selectedIndex = choices.getItemCount(); } choices.setSelectedIndex(selectedIndex); return; } if(keyCode == KEY_ENTER) { if(visible) { complete(); } return; } if(keyCode == KEY_ESCAPE) { choices.clear(); choicesPopup.hide(); visible = false; return; } String text = this.getText(); String[] matches = new String[]{}; String[] words = text.split(" |\n|\r"); text = words[words.length - 1]; typedText = text; 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(); visible = true; int nposy = this.getAbsoluteTop() + this.getOffsetHeight(); if(posy < 0 || nposy > posy) { posy = nposy; } choicesPopup.setPopupPosition(this.getAbsoluteLeft(), posy); //choicesPopup.setWidth(this.getOffsetWidth() + "px"); choices.setWidth(this.getOffsetWidth() + "px"); } } else { choicesPopup.hide(); visible = false; } } public void onChange(Widget sender) { complete(); } // add selected item to textarea protected void complete() { if(choices.getItemCount() > 0) { String text = this.getText(); text = text.substring(0, text.length() - typedText.length() - 1); text += choices.getItemText(choices.getSelectedIndex()); this.setText(text); this.setFocus(true); } choices.clear(); choicesPopup.hide(); } } /* Auto-Completion Textbox for GWT Copyright (C) 2006 Oliver Albers http://gwt.components.googlepages.com/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 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 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 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; } } /////////// .sPanel { width: 150px; height: 100px; position: absolute; left: 15px; top: 240px; } .panel { background-color: #C3D9FF; border: 1px solid #000000; padding: 3px; margin: 3px; font-weight: normal; }