📄 autocompleter.java
字号:
/*************************************************************************** * Copyright 2006-2008 by Christian Ihle * * kontakt@usikkert.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/package net.usikkert.kouchat.autocomplete;import java.util.ArrayList;import java.util.List;/** * This class can give suggestions for autocompleting words. * * At least one {@link AutoCompleteList} with some words is needed * to get results. * * @author Christian Ihle */public class AutoCompleter{ /** * The word that was used to build autocomplete suggestions in the * previous search. */ private String lastWord; /** * The suggested autocompleted word from previous search. */ private String lastCompletedWord; /** * The full line of text from the previous search, with the autocompleted * word replacing the original word. */ private String lastCompletedLine; /** * The position in the {@link #lastCompletedLine} that marks the end * of the {@link #lastCompletedWord}. Useful for setting the caret * at the end of the autocompleted word. */ private int newCaretPosition; /** * A list of {@link AutoCompleteList}s with support for different * kinds of words to autocomplete. */ private final List<AutoCompleteList> autoCompleteLists; /** * Constructor. Initializes variables. */ public AutoCompleter() { lastCompletedLine = ""; lastCompletedWord = ""; lastWord = ""; autoCompleteLists = new ArrayList<AutoCompleteList>(); } /** * Extracts the word at the given position from the line, * and looks for suggestions for autocompleting the word. * <br><br> * The previous search is saved, so if there are more than one * suggestion, repeated calls to this method will give the next * result in the suggestion list. * * @param line The line of text where the word to autocomplete is. * @param caretPosition The position in the line to look for the word. * @return The complete line, where the original word is replaced by * the suggested autocompleted word. * Use {@link #getNewCaretPosition()} to get the new caret position. */ public String completeWord( final String line, final int caretPosition ) { String completedLine = ""; if ( autoCompleteLists.size() > 0 ) { final int stop = findStopPosition( line, caretPosition ); final int start = findStartPosition( line, caretPosition ); final String word = line.substring( start, stop ); if ( word.trim().length() > 0 ) { final boolean continueLastSearch = continueLastSearch( word, line ); String checkword = ""; if ( continueLastSearch ) checkword = lastWord; else checkword = word; AutoCompleteList autoCompleteList = getAutoCompleteList( checkword ); if ( autoCompleteList != null ) { List<String> suggestions = getAutoCompleteSuggestions( autoCompleteList.getWordList(), checkword ); if ( suggestions.size() > 0 ) { int nextSuggestionPosition = findNextSuggestionPosition( continueLastSearch, suggestions, word ); String newWord = suggestions.get( nextSuggestionPosition ); completedLine = line.substring( 0, start ) + newWord; newCaretPosition = completedLine.length(); completedLine += line.substring( stop ); lastCompletedLine = completedLine; lastCompletedWord = newWord; if ( !continueLastSearch ) lastWord = word; } } } } return completedLine; } /** * Finds where in the list of suggestions to get the next suggestion. * * @param continueLastSearch If the previous search should be continued. * @param suggestions The list of suggested words. * @param word The word that is going to be autocompleted by the suggestion * this method finds. If this search continues from the previous * search, the word will be the same as the suggestion from that search. * @return The position in the list where the next suggestion can be found. */ private int findNextSuggestionPosition( final boolean continueLastSearch, final List<String> suggestions, final String word ) { int nextSuggestionPosition = -1; if ( continueLastSearch ) { // Locate the position of the previous suggestion in the list for ( int i = 0; i < suggestions.size(); i++ ) { if ( suggestions.get( i ).equals( word ) ) { nextSuggestionPosition = i; break; } } /* If more suggestions are available, increase position, * or else start from the beginning again. */ if ( nextSuggestionPosition > -1 && nextSuggestionPosition < suggestions.size() - 1 ) nextSuggestionPosition++; else nextSuggestionPosition = 0; } // New search, start with first suggestion if ( nextSuggestionPosition == -1 ) nextSuggestionPosition = 0; return nextSuggestionPosition; } /** * Checks if the new search should continue where the last left off. * The reason to continue is to see if there are more matches to the * previous search. * <br><br> * To find this, a check is done to see if the previous autocompleted * word and line is the same as the new word and line. If that's the case, * no changes to the text has been done since last autocomplete attempt. * * @param word The word to compare against the previous autocompleted word. * @param line The line to compare against the previous autocompleted line. * @return True if the search should be continued instead of restarted. */ private boolean continueLastSearch( final String word, final String line ) { return lastCompletedWord.equals( word ) && lastCompletedLine.equals( line ); } /** * Locates the position in the line where the word ends. * * @param line The line of text where the word is. * @param caretPosition The position in the line where the word is. * @return The position where the word ends. */ private int findStopPosition( final String line, final int caretPosition ) { int stop = line.indexOf( ' ', caretPosition ); if ( stop == -1 ) stop = line.length(); return stop; } /** * Locates the position in the line where the word starts. * * @param line The line of text where the word is. * @param caretPosition The position in the line where the word is. * @return The position where the word starts. */ private int findStartPosition( final String line, final int caretPosition ) { int start = line.lastIndexOf( ' ', caretPosition - 1 ); if ( start == -1 ) start = 0; else start++; return start; } /** * Asks the {@link AutoCompleteList}s available if any of them supports * this kind of word, and returns the match, if found. * * @param word The word to ask if any {@link AutoCompleteList} supports. * @return The first {@link AutoCompleteList} to support that word, * or <em>null</em> if none. */ private AutoCompleteList getAutoCompleteList( final String word ) { for ( AutoCompleteList acl : autoCompleteLists ) { if ( acl.acceptsWord( word ) ) { return acl; } } return null; } /** * Compares the word with the word list to find suggestions for * autocompleting the word. * * @param wordList A list of words to compare the word with. * @param word The word to get suggestions for. * @return A list of suggestions. */ private List<String> getAutoCompleteSuggestions( final String[] wordList, final String word ) { List<String> suggestions = new ArrayList<String>(); for ( int i = 0; i < wordList.length; i++ ) { if ( wordList[i].toLowerCase().startsWith( word.toLowerCase() ) ) { suggestions.add( wordList[i] ); } } return suggestions; } /** * Returns the new caret position for the last completed search. * * @return The new caret position. */ public int getNewCaretPosition() { return newCaretPosition; } /** * Adds a new {@link AutoCompleteList} to use for autocompletion. * * @param acl The list to add. */ public void addAutoCompleteList( final AutoCompleteList acl ) { autoCompleteLists.add( acl ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -