Primeiro você faz uma JComboBox normal. Se ela for Strict, você marca ela como “setEditable(false)”. Se ela não for strict, vc não faz isso.
Depois, você usa o AutoCompleteDecorator na sua ComboBox. E pronto!
V
ViniGodoy
Se vc quiser, pode usar essa classe que facilita esse processo:
importjava.awt.Color;importjava.awt.event.FocusEvent;importjava.awt.event.FocusListener;importjava.util.Collection;importjava.util.Vector;importjavax.swing.ComboBoxModel;importjavax.swing.JComboBox;importjavax.swing.UIManager;importjavax.swing.text.JTextComponent;publicclassAutoCompleteComboBoxextendsJComboBox{publicAutoCompleteComboBox(){super();initialize(false);}publicAutoCompleteComboBox(ComboBoxModelaModel){super(aModel);initialize(false);}publicAutoCompleteComboBox(Object...items){super(items);initialize(false);}publicAutoCompleteComboBox(Collection<?>items){super(newVector<Object>(items));initialize(false);}publicAutoCompleteComboBox(booleaneditable){super();initialize(editable);}publicAutoCompleteComboBox(ComboBoxModelaModel,booleaneditable){super(aModel);initialize(editable);}publicAutoCompleteComboBox(Collection<?>items,booleaneditable){super(newVector<Object>(items));initialize(editable);}privatevoidinitialize(booleaneditable){setEditable(editable);AutoCompleteDecorator.decorate(this);finalColorgray=getBackground();finalColorgreen=UIManager.getColor("ComboBox.selectionBackground");// final Color selection = ((JTextComponent)// getEditor().getEditorComponent()).getSelectionColor();getEditor().getEditorComponent().setBackground(gray);((JTextComponent)getEditor().getEditorComponent()).setSelectionColor(gray);((JTextComponent)getEditor().getEditorComponent()).setCaretColor(Color.white);((JTextComponent)getEditor().getEditorComponent()).setForeground(((JTextComponent)getEditor().getEditorComponent()).getSelectedTextColor());getEditor().getEditorComponent().addFocusListener(newFocusListener(){publicvoidfocusGained(FocusEvente){getEditor().getEditorComponent().setBackground(green);((JTextComponent)getEditor().getEditorComponent()).setSelectionColor(green);}publicvoidfocusLost(FocusEvente){getEditor().getEditorComponent().setBackground(gray);((JTextComponent)getEditor().getEditorComponent()).setSelectionColor(gray);}});}@OverridepublicvoidsetEnabled(booleanb){super.setEnabled(b);getEditor().getEditorComponent().setBackground(getBackground());}}
V
ViniGodoy
Nós também fizemos algumas correções no Decorator do SwingX:
importjava.awt.event.ActionEvent;importjava.awt.event.FocusAdapter;importjava.awt.event.FocusEvent;importjava.awt.event.KeyAdapter;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjava.beans.PropertyChangeEvent;importjava.beans.PropertyChangeListener;importjavax.swing.Action;importjavax.swing.ActionMap;importjavax.swing.ComboBoxEditor;importjavax.swing.InputMap;importjavax.swing.JComboBox;importjavax.swing.KeyStroke;importjavax.swing.UIManager;importjavax.swing.text.DefaultEditorKit;importjavax.swing.text.JTextComponent;importjavax.swing.text.TextAction;importorg.jdesktop.swingx.autocomplete.AbstractAutoCompleteAdaptor;importorg.jdesktop.swingx.autocomplete.AutoCompleteComboBoxEditor;importorg.jdesktop.swingx.autocomplete.AutoCompleteDocument;importorg.jdesktop.swingx.autocomplete.ComboBoxAdaptor;importorg.jdesktop.swingx.autocomplete.ObjectToStringConverter;importorg.jdesktop.swingx.autocomplete.workarounds.AquaLnFPopupLocationFix;/** * This class contains only static utility methods that can be used to set up * automatic completion for some Swing components. * <p> * Usage examples: * </p> * <p> * * <pre><code> * JComboBox comboBox = [...]; * AutoCompleteDecorator.<b>decorate</b>(comboBox); * * List items = [...]; * JTextField textField = [...]; * AutoCompleteDecorator.<b>decorate</b>(textField, items); * * JList list = [...]; * JTextField textField = [...]; * AutoCompleteDecorator.<b>decorate</b>(list, textField); * </code></pre> * * </p> * * @author Thomas Bierhance */publicclassAutoCompleteDecorator{/** * Enables automatic completion for the given JComboBox. The automatic * completion will be strict (only items from the combo box can be selected) * if the combo box is not editable. * * @param comboBox a combo box */publicstaticvoiddecorate(finalJComboBoxcomboBox){decorate(comboBox,ObjectToStringConverter.DEFAULT_IMPLEMENTATION);}/** * Enables automatic completion for the given JComboBox. The automatic * completion will be strict (only items from the combo box can be selected) * if the combo box is not editable. * * @param comboBox a combo box * @param stringConverter the converter used to transform items to strings */publicstaticvoiddecorate(finalJComboBoxcomboBox,finalObjectToStringConverterstringConverter){booleanstrictMatching=!comboBox.isEditable();// has to be editablecomboBox.setEditable(true);// fix the popup locationAquaLnFPopupLocationFix.install(comboBox);// configure the text component=editor componentJTextComponenteditorComponent=(JTextComponent)comboBox.getEditor().getEditorComponent();finalAbstractAutoCompleteAdaptoradaptor=newComboBoxAdaptor(comboBox);finalAutoCompleteDocumentdocument=newAutoCompleteDocument(adaptor,strictMatching,stringConverter);decorate(editorComponent,document,adaptor);// show the popup list when the user presses a keyfinalKeyListenerkeyListener=newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEventkeyEvent){// don't popup on action keys (cursor movements, etc...)if(keyEvent.isActionKey())return;// don't popup if the combobox isn't visible anywayif(comboBox.isDisplayable()&&!comboBox.isPopupVisible()){intkeyCode=keyEvent.getKeyCode();// don't popup when the user hits shift,ctrl or altif(keyCode==KeyEvent.VK_SHIFT||keyCode==KeyEvent.VK_CONTROL||keyCode==KeyEvent.VK_ALT)return;// don't popup when the user hits escape (see issue #311)if(keyCode==KeyEvent.VK_ESCAPE||keyCode==KeyEvent.VK_ENTER)return;if(keyEvent.isAltDown()||keyEvent.isControlDown())return;comboBox.setPopupVisible(true);}}};editorComponent.addKeyListener(keyListener);if(stringConverter!=ObjectToStringConverter.DEFAULT_IMPLEMENTATION){comboBox.setEditor(newAutoCompleteComboBoxEditor(comboBox.getEditor(),stringConverter));}// Changing the l&f can change the combobox' editor which in turn// would not be autocompletion-enabled. The new editor needs to be// set-up.comboBox.addPropertyChangeListener("editor",newPropertyChangeListener(){publicvoidpropertyChange(PropertyChangeEvente){ComboBoxEditoreditor=(ComboBoxEditor)e.getNewValue();if(editor!=null&&editor.getEditorComponent()!=null){if(!(editorinstanceofAutoCompleteComboBoxEditor)&&stringConverter!=ObjectToStringConverter.DEFAULT_IMPLEMENTATION){comboBox.setEditor(newAutoCompleteComboBoxEditor(editor,stringConverter));// Don't do the decorate step here because// calling setEditor will trigger// the propertychange listener a second time,// which will do the decorate// and addKeyListener step.}else{decorate((JTextComponent)editor.getEditorComponent(),document,adaptor);editor.getEditorComponent().addKeyListener(keyListener);}}}});}/** * Decorates a given text component for automatic completion using the given * AutoCompleteDocument and AbstractAutoCompleteAdaptor. * * @param textComponent a text component that should be decorated * @param document the AutoCompleteDocument to be installed on the text * component * @param adaptor the AbstractAutoCompleteAdaptor to be used */publicstaticvoiddecorate(JTextComponenttextComponent,AutoCompleteDocumentdocument,finalAbstractAutoCompleteAdaptoradaptor){// install the document on the text componenttextComponent.setDocument(document);// mark entire text when the text component gains focus// otherwise the last mark would have been retained which is quiet// confusingtextComponent.addFocusListener(newFocusAdapter(){@OverridepublicvoidfocusGained(FocusEvente){adaptor.markEntireText();}});// Tweak some key bindingsInputMapeditorInputMap=textComponent.getInputMap();if(document.isStrictMatching()){// move the selection to the left on VK_BACK_SPACEeditorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE,0),DefaultEditorKit.selectionBackwardAction);// ignore VK_DELETE and CTRL+VK_X and beep instead when strict// matchingeditorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE,0),errorFeedbackAction);editorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X,java.awt.event.InputEvent.CTRL_DOWN_MASK),errorFeedbackAction);}else{ActionMapeditorActionMap=textComponent.getActionMap();// leave VK_DELETE and CTRL+VK_X as is// VK_BACKSPACE will move the selection to the left if the selected// item is in the list// it will delete the previous character otherwiseeditorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE,0),"nonstrict-backspace");editorActionMap.put("nonstrict-backspace",newNonStrictBackspaceAction(editorActionMap.get(DefaultEditorKit.deletePrevCharAction),editorActionMap.get(DefaultEditorKit.selectionBackwardAction),adaptor));}}staticclassNonStrictBackspaceActionextendsTextAction{Actionbackspace;ActionselectionBackward;AbstractAutoCompleteAdaptoradaptor;publicNonStrictBackspaceAction(Actionbackspace,ActionselectionBackward,AbstractAutoCompleteAdaptoradaptor){super("nonstrict-backspace");this.backspace=backspace;this.selectionBackward=selectionBackward;this.adaptor=adaptor;}publicvoidactionPerformed(ActionEvente){if(adaptor.listContainsSelectedItem()){selectionBackward.actionPerformed(e);}else{backspace.actionPerformed(e);}}}/** * A TextAction that provides an error feedback for the text component that * invoked the action. The error feedback is most likely a "beep". */staticObjecterrorFeedbackAction=newTextAction("provide-error-feedback"){publicvoidactionPerformed(ActionEvente){UIManager.getLookAndFeel().provideErrorFeedback(getTextComponent(e));}};}
B
brlima
Quais correções?
V
ViniGodoy
Fizemos uns ajustes para ele trabalhar bem na JTable. Ele tinha uns problemas ao se pressionar ESC ou quando vc clicava no scroll enquanto o editor estava selecionado.
Mas agora nem estamos usando mais esse componente. Fizemos um novo combobox que, além do autocompletion, filtra também o seu interior. Tem até suporte a wildcards como *Product.
R
raci0nal
ViniGodoy,
Por acaso você não pode disponibilizar a parte do Filter do seu código?
Implementei um JComboBox com uma JTable como CellRenderer e estou tentando aplicar um filtro nos resultados disparando através do keyReleased do ComboEditor.
Porém, não estou conseguindo chegar a um resultado.
Obrigado.
ViniGodoy:
Fizemos uns ajustes para ele trabalhar bem na JTable. Ele tinha uns problemas ao se pressionar ESC ou quando vc clicava no scroll enquanto o editor estava selecionado.
Mas agora nem estamos usando mais esse componente. Fizemos um novo combobox que, além do autocompletion, filtra também o seu interior. Tem até suporte a wildcards como *Product.
V
ViniGodoy
Não dispare eventos através do comboeditor. O comboeditor é um JTextField, logo tem um Document associado. Você deve alterar esse Document. Vou ver se ajeito o código e posto aqui.
hum, essa nunca usei, mas o nome do pacote ali não é dos melhores…
H
habinovich
ViniGodoy:
Nós também fizemos algumas correções no Decorator do SwingX:
importjava.awt.event.ActionEvent;importjava.awt.event.FocusAdapter;importjava.awt.event.FocusEvent;importjava.awt.event.KeyAdapter;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjava.beans.PropertyChangeEvent;importjava.beans.PropertyChangeListener;importjavax.swing.Action;importjavax.swing.ActionMap;importjavax.swing.ComboBoxEditor;importjavax.swing.InputMap;importjavax.swing.JComboBox;importjavax.swing.KeyStroke;importjavax.swing.UIManager;importjavax.swing.text.DefaultEditorKit;importjavax.swing.text.JTextComponent;importjavax.swing.text.TextAction;importorg.jdesktop.swingx.autocomplete.AbstractAutoCompleteAdaptor;importorg.jdesktop.swingx.autocomplete.AutoCompleteComboBoxEditor;importorg.jdesktop.swingx.autocomplete.AutoCompleteDocument;importorg.jdesktop.swingx.autocomplete.ComboBoxAdaptor;importorg.jdesktop.swingx.autocomplete.ObjectToStringConverter;importorg.jdesktop.swingx.autocomplete.workarounds.AquaLnFPopupLocationFix;/** * This class contains only static utility methods that can be used to set up * automatic completion for some Swing components. * <p> * Usage examples: * </p> * <p> * * <pre><code> * JComboBox comboBox = [...]; * AutoCompleteDecorator.<b>decorate</b>(comboBox); * * List items = [...]; * JTextField textField = [...]; * AutoCompleteDecorator.<b>decorate</b>(textField, items); * * JList list = [...]; * JTextField textField = [...]; * AutoCompleteDecorator.<b>decorate</b>(list, textField); * </code></pre> * * </p> * * @author Thomas Bierhance */publicclassAutoCompleteDecorator{/** * Enables automatic completion for the given JComboBox. The automatic * completion will be strict (only items from the combo box can be selected) * if the combo box is not editable. * * @param comboBox a combo box */publicstaticvoiddecorate(finalJComboBoxcomboBox){decorate(comboBox,ObjectToStringConverter.DEFAULT_IMPLEMENTATION);}/** * Enables automatic completion for the given JComboBox. The automatic * completion will be strict (only items from the combo box can be selected) * if the combo box is not editable. * * @param comboBox a combo box * @param stringConverter the converter used to transform items to strings */publicstaticvoiddecorate(finalJComboBoxcomboBox,finalObjectToStringConverterstringConverter){booleanstrictMatching=!comboBox.isEditable();// has to be editablecomboBox.setEditable(true);// fix the popup locationAquaLnFPopupLocationFix.install(comboBox);// configure the text component=editor componentJTextComponenteditorComponent=(JTextComponent)comboBox.getEditor().getEditorComponent();finalAbstractAutoCompleteAdaptoradaptor=newComboBoxAdaptor(comboBox);finalAutoCompleteDocumentdocument=newAutoCompleteDocument(adaptor,strictMatching,stringConverter);decorate(editorComponent,document,adaptor);// show the popup list when the user presses a keyfinalKeyListenerkeyListener=newKeyAdapter(){@OverridepublicvoidkeyPressed(KeyEventkeyEvent){// don't popup on action keys (cursor movements, etc...)if(keyEvent.isActionKey())return;// don't popup if the combobox isn't visible anywayif(comboBox.isDisplayable()&&!comboBox.isPopupVisible()){intkeyCode=keyEvent.getKeyCode();// don't popup when the user hits shift,ctrl or altif(keyCode==KeyEvent.VK_SHIFT||keyCode==KeyEvent.VK_CONTROL||keyCode==KeyEvent.VK_ALT)return;// don't popup when the user hits escape (see issue #311)if(keyCode==KeyEvent.VK_ESCAPE||keyCode==KeyEvent.VK_ENTER)return;if(keyEvent.isAltDown()||keyEvent.isControlDown())return;comboBox.setPopupVisible(true);}}};editorComponent.addKeyListener(keyListener);if(stringConverter!=ObjectToStringConverter.DEFAULT_IMPLEMENTATION){comboBox.setEditor(newAutoCompleteComboBoxEditor(comboBox.getEditor(),stringConverter));}// Changing the l&f can change the combobox' editor which in turn// would not be autocompletion-enabled. The new editor needs to be// set-up.comboBox.addPropertyChangeListener("editor",newPropertyChangeListener(){publicvoidpropertyChange(PropertyChangeEvente){ComboBoxEditoreditor=(ComboBoxEditor)e.getNewValue();if(editor!=null&&editor.getEditorComponent()!=null){if(!(editorinstanceofAutoCompleteComboBoxEditor)&&stringConverter!=ObjectToStringConverter.DEFAULT_IMPLEMENTATION){comboBox.setEditor(newAutoCompleteComboBoxEditor(editor,stringConverter));// Don't do the decorate step here because// calling setEditor will trigger// the propertychange listener a second time,// which will do the decorate// and addKeyListener step.}else{decorate((JTextComponent)editor.getEditorComponent(),document,adaptor);editor.getEditorComponent().addKeyListener(keyListener);}}}});}/** * Decorates a given text component for automatic completion using the given * AutoCompleteDocument and AbstractAutoCompleteAdaptor. * * @param textComponent a text component that should be decorated * @param document the AutoCompleteDocument to be installed on the text * component * @param adaptor the AbstractAutoCompleteAdaptor to be used */publicstaticvoiddecorate(JTextComponenttextComponent,AutoCompleteDocumentdocument,finalAbstractAutoCompleteAdaptoradaptor){// install the document on the text componenttextComponent.setDocument(document);// mark entire text when the text component gains focus// otherwise the last mark would have been retained which is quiet// confusingtextComponent.addFocusListener(newFocusAdapter(){@OverridepublicvoidfocusGained(FocusEvente){adaptor.markEntireText();}});// Tweak some key bindingsInputMapeditorInputMap=textComponent.getInputMap();if(document.isStrictMatching()){// move the selection to the left on VK_BACK_SPACEeditorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE,0),DefaultEditorKit.selectionBackwardAction);// ignore VK_DELETE and CTRL+VK_X and beep instead when strict// matchingeditorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE,0),errorFeedbackAction);editorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X,java.awt.event.InputEvent.CTRL_DOWN_MASK),errorFeedbackAction);}else{ActionMapeditorActionMap=textComponent.getActionMap();// leave VK_DELETE and CTRL+VK_X as is// VK_BACKSPACE will move the selection to the left if the selected// item is in the list// it will delete the previous character otherwiseeditorInputMap.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE,0),"nonstrict-backspace");editorActionMap.put("nonstrict-backspace",newNonStrictBackspaceAction(editorActionMap.get(DefaultEditorKit.deletePrevCharAction),editorActionMap.get(DefaultEditorKit.selectionBackwardAction),adaptor));}}staticclassNonStrictBackspaceActionextendsTextAction{Actionbackspace;ActionselectionBackward;AbstractAutoCompleteAdaptoradaptor;publicNonStrictBackspaceAction(Actionbackspace,ActionselectionBackward,AbstractAutoCompleteAdaptoradaptor){super("nonstrict-backspace");this.backspace=backspace;this.selectionBackward=selectionBackward;this.adaptor=adaptor;}publicvoidactionPerformed(ActionEvente){if(adaptor.listContainsSelectedItem()){selectionBackward.actionPerformed(e);}else{backspace.actionPerformed(e);}}}/** * A TextAction that provides an error feedback for the text component that * invoked the action. The error feedback is most likely a "beep". */staticObjecterrorFeedbackAction=newTextAction("provide-error-feedback"){publicvoidactionPerformed(ActionEvente){UIManager.getLookAndFeel().provideErrorFeedback(getTextComponent(e));}};}
Irmao.. onde da pra pegar os jar's usados nessa classe
cara consegui implementar sua classe, mas me responde uma pergunta ele não filtra os dados da jComboBox sendo q os dados vem do banco?
att,
V
ViniGodoy
Devia filtrar qualquer coisa.
H
habinovich
Mesmo puxando os dados do banco?
pq qnd vou digitar ele não filtra mostra todos os dados q tem na tabela sem fazer o filtro e permanece assim ate terminar de digitar…
V
ViniGodoy
Ele filtra o conteúdo que estiver no combo. Não interessa se você carregou do banco, ou de qualquer outro lugar.
H
habinovich
Eh entao acho q estou fazendo algo muito errado…
qnd vc implemento ele o combo ficava em branco e na medida que ia digitar ele ia dando as opção que tem com as letras ja digitadas n era isso?
V
ViniGodoy
Isso… e é isso que é auto-complete. Você quer dar opções que não estão na combo? O que você quer exatamente?
H
habinovich
Me parece q agora esta dando certo mas ele ta mostrando o caminho do pacote no qual ta a beans da tabela!!!
P
philipemm
Olá a todos eu estou utilizando o auto complete do swingX tambem só que é em um JTextArea, o problema é que quando eu digito uma palavra ele até completa a palavra só que depois da palavra completada o que eu digito não aparece mais
Z
zicky23
boa tarde, desculpa ressussitar mais uma vez esse tópico mas qria saber como faço pra deixar meu jComboBox ou JTextField auto completável com essa classe???
aguardo uma ajuda…
valeu!!!
Z
zicky23
opa, consegui implementar da seguinte forma
espero que esteja certo.
// formata a comboprivatevoiddecoraComboContrib(){grafica.ClasseAutoComplete.decorate(ComboContrib);}//preenche a comboprivatevoidComboContrib(){ObjectcodSituacao,nomeSituacoes;conn.executeSQL("SELECT s.id_situacao,s.nome_situacoes"+" FROM SITUACOES s ORDER BY id_situacao");try{ComboContrib.addItem("Selecione");while(conn.resultset.next()){codSituacao=conn.resultset.getInt("id_situacao");nomeSituacoes=conn.resultset.getString("nome_situacoes");ComboContrib.addItem(nomeSituacoes);}}catch(SQLExceptionex){Logger.getLogger(NovoServico.class.getName()).log(Level.SEVERE,null,ex);}}
até ai blz, só gostaria de saber se tem como liberar a digitação para dados q nao estejam na combo.
tipo qro cadastrar outro tipo de situacao aki neste caso. tem como?