Java tutorial
/* SWT/JFace in Action GUI Design with Eclipse 3.0 Matthew Scarpino, Stephen Holder, Stanford Ng, and Laurent Mihalkovic ISBN: 1932394273 Publisher: Manning */ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextListener; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.TextEvent; import org.eclipse.jface.text.TextViewer; import org.eclipse.jface.text.contentassist.CompletionProposal; import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.contentassist.ContextInformationValidator; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.jface.text.contentassist.IContextInformationValidator; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; public class Ch5CompletionEditor extends Composite { private TextViewer textViewer; private WordTracker wordTracker; private static final int MAX_QUEUE_SIZE = 200; public Ch5CompletionEditor(Composite parent) { super(parent, SWT.NULL); wordTracker = new WordTracker(MAX_QUEUE_SIZE); buildControls(); } private void buildControls() { setLayout(new FillLayout()); textViewer = new TextViewer(this, SWT.MULTI | SWT.V_SCROLL); textViewer.setDocument(new Document()); final ContentAssistant assistant = new ContentAssistant(); assistant.setContentAssistProcessor(new RecentWordContentAssistProcessor(wordTracker), IDocument.DEFAULT_CONTENT_TYPE); assistant.install(textViewer); textViewer.getControl().addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { switch (e.keyCode) { case SWT.F1: assistant.showPossibleCompletions(); break; default: //ignore everything else } } }); textViewer.addTextListener(new ITextListener() { public void textChanged(TextEvent e) { if (isWhitespaceString(e.getText())) { wordTracker.add(findMostRecentWord(e.getOffset() - 1)); } } }); } protected String findMostRecentWord(int startSearchOffset) { int currOffset = startSearchOffset; char currChar; String word = ""; try { while (currOffset > 0 && !Character.isWhitespace(currChar = textViewer.getDocument().getChar(currOffset))) { word = currChar + word; currOffset--; } return word; } catch (BadLocationException e) { e.printStackTrace(); return null; } } protected boolean isWhitespaceString(String string) { StringTokenizer tokenizer = new StringTokenizer(string); //if there is at least 1 token, this string is not whitespace return !tokenizer.hasMoreTokens(); } } class WordTracker { private int maxQueueSize; private List wordBuffer; private Map knownWords = new HashMap(); public WordTracker(int queueSize) { maxQueueSize = queueSize; wordBuffer = new LinkedList(); } public int getWordCount() { return wordBuffer.size(); } public void add(String word) { if (wordIsNotKnown(word)) { flushOldestWord(); insertNewWord(word); } } private void insertNewWord(String word) { wordBuffer.add(0, word); knownWords.put(word, word); } private void flushOldestWord() { if (wordBuffer.size() == maxQueueSize) { String removedWord = (String) wordBuffer.remove(maxQueueSize - 1); knownWords.remove(removedWord); } } private boolean wordIsNotKnown(String word) { return knownWords.get(word) == null; } public List suggest(String word) { List suggestions = new LinkedList(); for (Iterator i = wordBuffer.iterator(); i.hasNext();) { String currWord = (String) i.next(); if (currWord.startsWith(word)) { suggestions.add(currWord); } } return suggestions; } } class RecentWordContentAssistProcessor implements IContentAssistProcessor { private String lastError = null; private IContextInformationValidator contextInfoValidator; private WordTracker wordTracker; public RecentWordContentAssistProcessor(WordTracker tracker) { super(); contextInfoValidator = new ContextInformationValidator(this); wordTracker = tracker; } public ICompletionProposal[] computeCompletionProposals(ITextViewer textViewer, int documentOffset) { IDocument document = textViewer.getDocument(); int currOffset = documentOffset - 1; try { String currWord = ""; char currChar; while (currOffset > 0 && !Character.isWhitespace(currChar = document.getChar(currOffset))) { currWord = currChar + currWord; currOffset--; } List suggestions = wordTracker.suggest(currWord); ICompletionProposal[] proposals = null; if (suggestions.size() > 0) { proposals = buildProposals(suggestions, currWord, documentOffset - currWord.length()); lastError = null; } return proposals; } catch (BadLocationException e) { e.printStackTrace(); lastError = e.getMessage(); return null; } } private ICompletionProposal[] buildProposals(List suggestions, String replacedWord, int offset) { ICompletionProposal[] proposals = new ICompletionProposal[suggestions.size()]; int index = 0; for (Iterator i = suggestions.iterator(); i.hasNext();) { String currSuggestion = (String) i.next(); proposals[index] = new CompletionProposal(currSuggestion, offset, replacedWord.length(), currSuggestion.length()); index++; } return proposals; } public IContextInformation[] computeContextInformation(ITextViewer textViewer, int documentOffset) { lastError = "No Context Information available"; return null; } public char[] getCompletionProposalAutoActivationCharacters() { //we always wait for the user to explicitly trigger completion return null; } public char[] getContextInformationAutoActivationCharacters() { //we have no context information return null; } public String getErrorMessage() { return lastError; } public IContextInformationValidator getContextInformationValidator() { return contextInfoValidator; } }