View Full Version : [Java]completamento automatico su textfield
...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...
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:
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??
Perchè sei matto anche tu? :D
...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...
vBulletin® v3.6.4, Copyright ©2000-2024, Jelsoft Enterprises Ltd.