Autocomplete em combobox, funciona, mas não certo

6 respostas
zerokelvin

Pessoal, tenho as classes a baixo
Essas são conhecidas ae. O problema é que não sei como fazer pra ele REALMENTE ficar editável, ou seja, quando o usuário digitar um valor que não está na lista, ele permitir que o usuário digite normalmente. Já baixei e testei várias classes, tentei mexer, mas nã acho isso. Dae coloco um listener que fará a consulta, se o valor não existir, ele abrirá uma tela para cadastro.

Acho q é simples, mas sou dos iniciantes!
valeu ae.

import java.awt.event.ItemEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.plaf.basic.BasicComboBoxEditor;

public class Java2sAutoComboBox extends JComboBox {
  private class AutoTextFieldEditor extends BasicComboBoxEditor {

    private Java2sAutoTextField getAutoTextFieldEditor() {
      return (Java2sAutoTextField) editor;
    }

    AutoTextFieldEditor(java.util.List list) {
      editor = new Java2sAutoTextField(list, Java2sAutoComboBox.this);
    }
  }

  public Java2sAutoComboBox(java.util.List list) {
    isFired = false;
    autoTextFieldEditor = new AutoTextFieldEditor(list);
    setEditable(true);
    setModel(new DefaultComboBoxModel(list.toArray()) {

      protected void fireContentsChanged(Object obj, int i, int j) {
        if (!isFired)
          super.fireContentsChanged(obj, i, j);
      }

    });
    setEditor(autoTextFieldEditor);
  }

  public boolean isCaseSensitive() {
    return autoTextFieldEditor.getAutoTextFieldEditor().isCaseSensitive();
  }

  public void setCaseSensitive(boolean flag) {
    autoTextFieldEditor.getAutoTextFieldEditor().setCaseSensitive(flag);
  }

  public boolean isStrict() {
    return autoTextFieldEditor.getAutoTextFieldEditor().isStrict();
  }

  public void setStrict(boolean flag) {
    autoTextFieldEditor.getAutoTextFieldEditor().setStrict(flag);
  }

  public java.util.List getDataList() {
    return autoTextFieldEditor.getAutoTextFieldEditor().getDataList();
  }

  public void setDataList(java.util.List list) {
    autoTextFieldEditor.getAutoTextFieldEditor().setDataList(list);
    setModel(new DefaultComboBoxModel(list.toArray()));
  }

  void setSelectedValue(Object obj) {
    if (isFired) {
      return;
    } else {
      isFired = true;
      setSelectedItem(obj);
      fireItemStateChanged(new ItemEvent(this, 701, selectedItemReminder,
          1));
      isFired = false;
      return;
    }
  }

  protected void fireActionEvent() {
    if (!isFired)
      super.fireActionEvent();
  }

  private AutoTextFieldEditor autoTextFieldEditor;

  private boolean isFired;

}
import java.util.List;
import javax.swing.JTextField;
import javax.swing.text.*;

public class Java2sAutoTextField extends JTextField {
  class AutoDocument extends PlainDocument {

    public void replace(int i, int j, String s, AttributeSet attributeset)
        throws BadLocationException {
      super.remove(i, j);
      insertString(i, s, attributeset);
    }

    public void insertString(int i, String s, AttributeSet attributeset)
        throws BadLocationException {
      if (s == null || "".equals(s))
        return;
      String s1 = getText(0, i);
      String s2 = getMatch(s1 + s);
      int j = (i + s.length()) - 1;
      if (isStrict && s2 == null) {
        s2 = getMatch(s1);
        j--;
      } else if (!isStrict && s2 == null) {
        super.insertString(i, s, attributeset);
        return;
      }
      if (autoComboBox != null && s2 != null)
        autoComboBox.setSelectedValue(s2);
      super.remove(0, getLength());
      super.insertString(0, s2, attributeset);
      setSelectionStart(j + 1);
      setSelectionEnd(getLength());
    }

    public void remove(int i, int j) throws BadLocationException {
      int k = getSelectionStart();
      if (k > 0)
        k--;
      String s = getMatch(getText(0, k));
      if (!isStrict && s == null) {
        super.remove(i, j);
      } else {
        super.remove(0, getLength());
        super.insertString(0, s, null);
      }
      if (autoComboBox != null && s != null)
        autoComboBox.setSelectedValue(s);
      try {
        setSelectionStart(k);
        setSelectionEnd(getLength());
      } catch (Exception exception) {
      }
    }

  }

  public Java2sAutoTextField(List list) {
    isCaseSensitive = false;
    isStrict = true;
    autoComboBox = null;
    if (list == null) {
      throw new IllegalArgumentException("values can not be null");
    } else {
      dataList = list;
      init();
      return;
    }
  }

  Java2sAutoTextField(List list, Java2sAutoComboBox b) {
    isCaseSensitive = false;
    isStrict = true;
    autoComboBox = null;
    if (list == null) {
      throw new IllegalArgumentException("values can not be null");
    } else {
      dataList = list;
      autoComboBox = b;
      init();
      return;
    }
  }

  private void init() {
    setDocument(new AutoDocument());
    if (isStrict && dataList.size() > 0)
      setText(dataList.get(0).toString());
  }

  private String getMatch(String s) {
    for (int i = 0; i < dataList.size(); i++) {
      String s1 = dataList.get(i).toString();
      if (s1 != null) {
        if (!isCaseSensitive
            && s1.toLowerCase().startsWith(s.toLowerCase()))
          return s1;
        if (isCaseSensitive && s1.startsWith(s))
          return s1;
      }
    }

    return null;
  }

  public void replaceSelection(String s) {
    AutoDocument _lb = (AutoDocument) getDocument();
    if (_lb != null)
      try {
        int i = Math.min(getCaret().getDot(), getCaret().getMark());
        int j = Math.max(getCaret().getDot(), getCaret().getMark());
        _lb.replace(i, j - i, s, null);
      } catch (Exception exception) {
      }
  }

  public boolean isCaseSensitive() {
    return isCaseSensitive;
  }

  public void setCaseSensitive(boolean flag) {
    isCaseSensitive = flag;
  }

  public boolean isStrict() {
    return isStrict;
  }

  public void setStrict(boolean flag) {
    isStrict = flag;
  }

  public List getDataList() {
    return dataList;
  }

  public void setDataList(List list) {
    if (list == null) {
      throw new IllegalArgumentException("values can not be null");
    } else {
      dataList = list;
      return;
    }
  }

  private List dataList;

  private boolean isCaseSensitive;

  private boolean isStrict;

  private Java2sAutoComboBox autoComboBox;
}

6 Respostas

zerokelvin

ninguem???

walissongpi

Não entendi sua dúvida. Pode se expressar de outra maneira? :wink:

zerokelvin

bom, o combo do código não fica editável exatamente. O cursos “anda” na palavra e ele vai selecionando o valor da lista que bate com o que é digitado. então suponhamos que tenho 2 valores no list do combo:

“zero”
“wallison”

Se digito “w” ele aparece wallison no total, inclusive o cursor anda no nome, mas se digito “wP”, o p não entra, porque não há nada na lista com “wP”, e preciso que quando nao houver, na lista, a letra ou sequencia de letras digitada, o combo permita que eu continue digitando, mas obviamente sem autocompletar nada… ou seja, ele precisa me permitir digitar o que eu quiser, como um TextField sem máscara, MAS quando o valor que digito estiver na lista ou parte dele, o autocompletar funciona.

Tá meio confuso mesmo… mas espero que tenha ficado mais claro.
valeu mesmo por enquanto.

walissongpi

zerokelvin:
bom, o combo do código não fica editável exatamente. O cursos “anda” na palavra e ele vai selecionando o valor da lista que bate com o que é digitado. então suponhamos que tenho 2 valores no list do combo:

“zero”
“wallison”

Se digito “w” ele aparece wallison no total, inclusive o cursor anda no nome, mas se digito “wP”, o p não entra, porque não há nada na lista com “wP”, e preciso que quando nao houver, na lista, a letra ou sequencia de letras digitada, o combo permita que eu continue digitando, mas obviamente sem autocompletar nada… ou seja, ele precisa me permitir digitar o que eu quiser, como um TextField sem máscara, MAS quando o valor que digito estiver na lista ou parte dele, o autocompletar funciona.

Tá meio confuso mesmo… mas espero que tenha ficado mais claro.
valeu mesmo por enquanto.

Poste todo o seu código para que eu possa visualiza-lo. :stuck_out_tongue:

zerokelvin

São aqueles dois mais esse, que apenas exibe o combo pra teste:

public class TesteCombo{
public static void main(String[] args){
  JFrame f = new JFrame("teste");
         f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
         f.setSize(300,300);
         Container cp= f.getContentPane();
         //cp.setLayout(null);
java.util.List<String> lista = new ArrayList<String>();  
lista.add ("man"); 
lista.add ("man2");    
lista.add ("ppppq");   
lista.add ("bla");  
//Java2sAutoComboBox jc = new Java2sAutoComboBox(lista);
AutoCompleteComboBox jc = new AutoCompleteComboBox(lista);
jc.setEditable(true);
//jc.setStrict(false);
cp.add(jc);
f.setVisible(true);
}
zerokelvin

Alguem faz idéia d como resolvo isso?

Criado 4 de maio de 2010
Ultima resposta 5 de mai. de 2010
Respostas 6
Participantes 2