Java/GWT/Auto Completion

Материал из Java эксперт
Перейти к: навигация, поиск

Auto-Completion Textbox for GWT

package com.jexp.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.ruponents.googlepages.ru/
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.ruponents.googlepages.ru/
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].rupareTo(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.ruponents.googlepages.ru/
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].rupareTo(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.ruponents.googlepages.ru/
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;  
}