PDA

View Full Version : [Java]completamento automatico su textfield


ally
23-09-2009, 13:51
...ciao...

...come da titolo...come si imposta il completamento automatico su una text field che pesca i propri valori da una tabella db?...avete esperienze in merito?...

...ciao Andrea...

PGI-Bis
23-09-2009, 15:43
Un programmatore non imposta, realizza!

:D

Completamento automatico 101

Prendi il Document del campo di testo, quando il contenuto cambia consideri come iniziale del testo la porzione che va da 0 a getCaretPosition(). Fai la ricerca nel database, trovi la migliore corrispondenza, imposti come testo attuale la corrispondenza e selezioni (setSelectionStart, setSelectionEnd) la porzione di testo da getCaretPosition() a getLength().

Et voilà.

banryu79
23-09-2009, 17:38
ally, devi solo risolvere questo:

Fai la ricerca nel database, trovi la migliore corrispondenza...

:Prrr:

PGI-Bis
23-09-2009, 20:00
Su un Athlon XP3200 con un dizionario di 704938 parole interamente caricato in memoria (circa 50 megabyte) una semplice scansione lineare con un "word.startsWith(prefisso)" richiede circa 2 centesimi di secondo nel caso peggiore. Considerando che le performace di un homo-digitans medio si attestano sui 2 o 3 caratteri al secondo non risulterebbero problemi di "lag" nell'interazione utente.

morskott
24-09-2009, 00:16
Un programmatore non imposta, realizza!



Questa me la segno!!!!

PS: perchè (non solo in questo 3d) mi trovo sempre d'accordo con te??

PGI-Bis
24-09-2009, 00:39
Perchè sei matto anche tu? :D

ally
01-10-2009, 10:25
...ecco la soluzione al mio cruccio...se mai dovesse servire a qualcuno...presa e legerissimamente modificata da java2s...


public class AutoTextField 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 (AutoTextField.this.isStrict && s2 == null) {
s2 = getMatch(s1);
j--;
} else if (!AutoTextField.this.isStrict && s2 == null) {
super.insertString(i, s, attributeset);
return;
}
if (AutoTextField.this.autoComboBox != null && s2 != null)
AutoTextField.this.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 (!AutoTextField.this.isStrict && s == null) {
super.remove(i, j);
} else {
super.remove(0, getLength());
super.insertString(0, s, null);
}
if (AutoTextField.this.autoComboBox != null && s != null)
AutoTextField.this.autoComboBox.setSelectedValue(s);
try {
setSelectionStart(k);
setSelectionEnd(getLength());
} catch (Exception exception) {
//
}
}

}

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

}

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

private void init() {

setDocument(new AutoDocument());
if (this.isStrict && this.dataList.size() > 0)
setText(this.dataList.get(0).toString());
}

String getMatch(String s) {

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

}
}

return s;
}

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) {
System.out.println(exception);
}
}

public boolean isCaseSensitive() {
return this.isCaseSensitive;
}

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

public boolean isStrict() {
return this.isStrict;
}

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

public List getDataList() {
return this.dataList;
}

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

private List dataList;

private boolean isCaseSensitive;

boolean isStrict;

AutoComboBox autoComboBox;
}



public class AutoComboBox extends JComboBox {

private class AutoTextFieldEditor extends BasicComboBoxEditor {

private AutoTextField getAutoTextFieldEditor() {
return (AutoTextField) this.editor;
}

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

public AutoComboBox(java.util.List list) {

this.isFired = false;
this.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(AutoComboBox.this.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) {

System.out.println("setSelectedValue");

if (AutoComboBox.this.isFired)
return;
AutoComboBox.this.isFired = true;
setSelectedItem(obj);
fireItemStateChanged(new ItemEvent(this, 701, AutoComboBox.this.selectedItemReminder,
1));
AutoComboBox.this.isFired = false;
return;

}

protected void fireActionEvent() {

System.out.println("fireActionEvent");

if (!AutoComboBox.this.isFired)
super.fireActionEvent();
}

private AutoTextFieldEditor autoTextFieldEditor;

private boolean isFired;

}



...in sinto una comboBox travestita da textField...


String getMatch(String s) {

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

}
}

return s;
}


...per evitare l'editabilità della lista...per impedire dunque che il text field possa assumere valori diversi da quanto imposto dalla list è necessario eliminare il return nel metodo qui evidenziato facente parte di AutoTextField...

...ciao Andrea...

Fire Fox II
15-03-2011, 09:53
Sto provando un pò la soluzione fornita da Andrea/java2s ...

Non riesco a capire se c'è qualche errore o sbaglio qualcosa io...

Io vorrei fare in modo che ad ogni lettera digitata, mi compaia una lista di possibili soluzioni: per farlo l'unico modo è chiamare AutoComboBox, ma io vorrei ottenerlo con il textField...

Ora ci sono i 2 costruttori

AutoTextField(List list)
AutoTextField(List list, AutoComboBox b)

e teoricamente il secondo dovrebbe essere la soluzione al mio problema, ma praticamente non ottengo alcuna differenza chiamando l'uno o l'altro...

Non so se qualcuno ha provato...