Автозаполнение может быть очень полезно практически в любом приложении, но его нетривиально реализовать. Итак, вот краткий пример того, как вы могли бы сделать это в Java-фреймворке Swing с JTextField (он также должен работать с JTextArea с небольшими изменениями). Этот пример представляет собой модифицированную версию примера Oracle [http://docs.oracle.com/javase/tutorial/uiswing/components/textarea.html]. Пакет кода com.example.myapp.console; import java.awt.event.ActionEvent; import java.util.Collections; я
Автозаполнение может быть очень полезно практически в любом приложении,
но его нетривиально реализовать. Итак, вот краткий пример того, как вы
могли бы сделать это в Java-фреймворке Swing с JTextField (он также
должен работать с JTextArea с небольшими изменениями). Этот пример
представляет собой модифицированную версию примера
Oracle
.
packagecom.example.myapp.console;importjava.awt.event.ActionEvent;importjava.util.Collections;importjava.util.List;importjavax.swing.AbstractAction;importjavax.swing.JTextField;importjavax.swing.SwingUtilities;importjavax.swing.event.DocumentEvent;importjavax.swing.event.DocumentListener;importjavax.swing.text.BadLocationException;publicclassAutocompleteimplementsDocumentListener{privatestaticenumMode{INSERT,COMPLETION};privateJTextFieldtextField;privatefinalList<String>keywords;privateModemode=Mode.INSERT;publicAutocomplete(JTextFieldtextField,List<String>keywords){this.textField=textField;this.keywords=keywords;Collections.sort(keywords);}@OverridepublicvoidchangedUpdate(DocumentEventev){}@OverridepublicvoidremoveUpdate(DocumentEventev){}@OverridepublicvoidinsertUpdate(DocumentEventev){if(ev.getLength()!=1)return;intpos=ev.getOffset();Stringcontent=null;try{content=textField.getText(0,pos+1);}catch(BadLocationExceptione){e.printStackTrace();}// Find where the word starts
intw;for(w=pos;w>=0;w--){if(!Character.isLetter(content.charAt(w))){break;}}// Too few chars
if(pos-w<2)return;Stringprefix=content.substring(w+1).toLowerCase();intn=Collections.binarySearch(keywords,prefix);if(n<0&&-n<=keywords.size()){Stringmatch=keywords.get(-n-1);if(match.startsWith(prefix)){// A completion is found
Stringcompletion=match.substring(pos-w);// We cannot modify Document from within notification,
// so we submit a task that does the change later
SwingUtilities.invokeLater(newCompletionTask(completion,pos+1));}}else{// Nothing found
mode=Mode.INSERT;}}publicclassCommitActionextendsAbstractAction{/**
*
*/privatestaticfinallongserialVersionUID=5794543109646743416L;@OverridepublicvoidactionPerformed(ActionEventev){if(mode==Mode.COMPLETION){intpos=textField.getSelectionEnd();StringBuffersb=newStringBuffer(textField.getText());sb.insert(pos," ");textField.setText(sb.toString());textField.setCaretPosition(pos+1);mode=Mode.INSERT;}else{textField.replaceSelection("\t");}}}privateclassCompletionTaskimplementsRunnable{privateStringcompletion;privateintposition;CompletionTask(Stringcompletion,intposition){this.completion=completion;this.position=position;}publicvoidrun(){StringBuffersb=newStringBuffer(textField.getText());sb.insert(position,completion);textField.setText(sb.toString());textField.setCaretPosition(position+completion.length());textField.moveCaretPosition(position);mode=Mode.COMPLETION;}}}
Использование кода
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
privatestaticfinalStringCOMMIT_ACTION="commit";JTextFieldmainTextField=newJTextField();// Without this, cursor always leaves text field
mainTextField.setFocusTraversalKeysEnabled(false);...// Our words to complete
keywords=newArrayList<String>(5);keywords.add("example");keywords.add("autocomplete");keywords.add("stackabuse");keywords.add("java");AutocompleteautoComplete=newAutocomplete(mainTextField,keywords);mainTextField.getDocument().addDocumentListener(autoComplete);// Maps the tab key to the commit action, which finishes the autocomplete
// when given a suggestion
mainTextField.getInputMap().put(KeyStroke.getKeyStroke("TAB"),COMMIT_ACTION);mainTextField.getActionMap().put(COMMIT_ACTION,autoComplete.newCommitAction());
Если вы хотите, чтобы список ключевых слов в вашем приложении со
временем менялся (например, если вы автоматически заполняете имена
друзей онлайн в приложении чата), то все, что вам нужно сделать, это
добавить метод установки в Autocomplete for List<String> keywords и
обновите список ключевых слов нужным Strings