Автозаполнение jtextfield от определенной длины
Я хочу выполнить автозаполнение jtextfield, для этого я нашел его в Google и нашел несколько хороших примеров и фрагментов кода, но мой сценарий отличается от всех этих, обычно каждый пример автоматически заполняет поле, например, скажем, если я нажимаю Если он будет автоматически заполнен с помощью Stackru, или, если я нажму G, он завершит работу с Google и т. Д., То есть для автозаполнения потребуется только первый символ.
Но моя проблема заключается в том, что я хочу выполнить автозаполнение, когда первые 4 символа будут напечатаны или введены, скажем, если я набрал stac, то следует автоматически завершить его до stackru, а не с первым символом S.
Пожалуйста, покажите мне, как мне это сделать. Я очень сильно застрял в этой проблеме.
следующий код, который я использую для моего рабочего класса
package testautocomp;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
public class JTextFieldAutoCompletion extends JTextField implements DocumentListener, ActionListener{
/**
*
*/
private static final long serialVersionUID = 4810213451949301347L;
//Les Données De L'AutoCompletion
private List<String> data = new ArrayList<String>();
//Un Constructeur Par Défaut
public JTextFieldAutoCompletion() {
//Par Defaut Le Nombre de caractère visible dans le champs de texte est 25
this(25);
}
/**
* Un Constructeur Paramétré
* @param columns nombre de caractère visible dans le champs de texte
*/
public JTextFieldAutoCompletion(int columns) {
//passer au constructeur à deux arguments le nombre de colonne visible dans le champs de texte et definir les données de l'autocompletion à null.
this(columns, null);
}
/**
* Constructeur Paramétré à deux arguments
* @param columns nombre de caractère visible dans le champs de texte
* @param data les données de l'autocompletion
*/
public JTextFieldAutoCompletion(int columns, List<String> data) {
super(columns);
//ici on fait appel à la méthode setDataCompletion pour definir les données de l'autocompletion
this.setDataCompletion(data);
//je défini l'ecouteur de l'evenement de la saisie
this.getDocument().addDocumentListener(this);
//je défini j'ecouteur de la touche entrer
this.addActionListener(this);
}
/**
* Permet De Redefinir les données de l'autocompletion
* @param data les données de l'autocompletion
*/
public void setDataCompletion(List<String> data) {
//on affecte seulement si data est déffirent à null
if(data != null)
this.data = data;
//on va trier les données de l'autocompletion
Collections.sort(this.data);
}
/**
* Evenement Déclenché à chaque fois que l'utilisateur tape un caractère quelconque, ou fasse une copier/coller dans le champs de texte.
*/
@Override
public void insertUpdate(DocumentEvent e) {
// TODO Stub de la méthode généré automatiquement
//on arréte l'exécution de l'evenement si l'utilisateur fasse une copier/coller
if(e.getLength() != 1) return;
//on récupére la position du dernier caratère saisie en comptant de zéro, premier caractère est en position 0, le deuxième à 2 etc..
int pos = e.getOffset();
String prefix = null;
try {
//on recupére dans prefix ce qu'a saisi l'utilisateur jusqu'à présent.
prefix = this.getText(0, pos + 1);
} catch (BadLocationException e1) {}
//on fait une recherche sur la chaine qu'a saisi l'utilisateur dans les données de l'autocompletion.
//la méthode binarySearch retourne :
//Soit l'index de l'element cherché s'il est contenu dans la collection.
//Soit le nombre d'element de la collection si tous les elements sont inférieurs à l'element qu'on cherche.
//Soit un entier négatif qui représente l'index de premier element supérieur de l'element qu'on cherche.
int index = Collections.binarySearch(data, prefix);
if(index < 0 && -index <= data.size()) {
//Completion Trouvé
//On récupére le premier element supérieur à l'element cherché. le signe - retourne la valeur absolue de la variable index.
String match = data.get(-index - 1);
//on s'assure que la chaine dans la variable match commence par la chaine contenu dans la variable prefix c-à-d ce qu'a saisi l'utilisateur
if(match.startsWith(prefix)) {
//si oui on met on place l'autocompletion sinon on fait rien :).
SwingUtilities.invokeLater(new AutoCompletion(pos, match));
}
} else ;
//Aucune Completion Trouvé
}
/**
* Permet De Valider L'AutoCompletion En Cliquant Sur La Touche Entrer
*/
@Override
public void actionPerformed(ActionEvent e) {
// TODO Stub de la méthode généré automatiquement
setCaretPosition(getSelectionEnd());
}
@Override
public void removeUpdate(DocumentEvent e) {}
@Override
public void changedUpdate(DocumentEvent e) {}
private class AutoCompletion implements Runnable{
private int pos;
private String completion;
public AutoCompletion(int pos, String completion) {
this.pos = pos;
this.completion = completion;
}
@Override
public void run() {
// TODO Stub de la méthode généré automatiquement
//On affecte la chaine trouvé pour l'autocompletion dans le champs de texte
setText(completion);
//on definit à partir d'où va débuter la séléction des caractères ajouté comme completion.
//j'ai précisé qu'il va débuter de la fin vers le dernier caractère sasie par l'utilisateur
setCaretPosition(completion.length());
//j'ai appliqué la séléction jusqu'au dernier caractère sasie par l'utilisateur
moveCaretPosition(pos + 1);
}
}
}
и вот мой основной класс
package testautocomp;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class TestAutoComp {
public static void main(String[] a) {
JFrame f = new JFrame();
JTextFieldAutoCompletion tf = new JTextFieldAutoCompletion(25);
List<String> data = new ArrayList<String>();
data.add("jtextfield autocompletion");
data.add("java swing");
data.add("je veux apprendre java");
data.add("stackru");
data.add("ahad");
tf.setDataCompletion(data);
f.getContentPane().add(tf, "North");
f.pack();f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
1 ответ
В соответствии с вашим вопросом вы хотите выполнить автозаполнение, когда будут набраны первые 4 символа. Затем просто дайте проверку в вашем методе insertUpdate(), чтобы длина текста в текстовом поле была больше 3, поэтому вы получите ожидаемый результат. Я изменил ваш код для ожидаемого результата.
package temp;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
public class JTextFieldAutoCompletion extends JTextField implements DocumentListener, ActionListener{
/**
*
*/
private static final long serialVersionUID = 4810213451949301347L;
//Les Données De L'AutoCompletion
private List<String> data = new ArrayList<String>();
//Un Constructeur Par Défaut
public JTextFieldAutoCompletion() {
//Par Defaut Le Nombre de caractère visible dans le champs de texte est 25
this(25);
}
/**
* Un Constructeur Paramétré
* @param columns nombre de caractère visible dans le champs de texte
*/
public JTextFieldAutoCompletion(int columns) {
//passer au constructeur à deux arguments le nombre de colonne visible dans le champs de texte et definir les données de l'autocompletion à null.
this(columns, null);
}
/**
* Constructeur Paramétré à deux arguments
* @param columns nombre de caractère visible dans le champs de texte
* @param data les données de l'autocompletion
*/
public JTextFieldAutoCompletion(int columns, List<String> data) {
super(columns);
//ici on fait appel à la méthode setDataCompletion pour definir les données de l'autocompletion
this.setDataCompletion(data);
//je défini l'ecouteur de l'evenement de la saisie
this.getDocument().addDocumentListener(this);
//je défini j'ecouteur de la touche entrer
this.addActionListener(this);
}
/**
* Permet De Redefinir les données de l'autocompletion
* @param data les données de l'autocompletion
*/
public void setDataCompletion(List<String> data) {
//on affecte seulement si data est déffirent à null
if(data != null)
this.data = data;
//on va trier les données de l'autocompletion
Collections.sort(this.data);
}
/**
* Evenement Déclenché à chaque fois que l'utilisateur tape un caractère quelconque, ou fasse une copier/coller dans le champs de texte.
*/
@Override
public void insertUpdate(DocumentEvent e) {
// TODO Stub de la méthode généré automatiquement
//on arréte l'exécution de l'evenement si l'utilisateur fasse une copier/coller
if(this.getText().length()>3){
if(e.getLength() != 1) return;
//on récupére la position du dernier caratère saisie en comptant de zéro, premier caractère est en position 0, le deuxième à 2 etc..
int pos = e.getOffset();
String prefix = null;
try {
//on recupére dans prefix ce qu'a saisi l'utilisateur jusqu'à présent.
prefix = this.getText(0, pos + 1);
} catch (BadLocationException e1) {}
//on fait une recherche sur la chaine qu'a saisi l'utilisateur dans les données de l'autocompletion.
//la méthode binarySearch retourne :
//Soit l'index de l'element cherché s'il est contenu dans la collection.
//Soit le nombre d'element de la collection si tous les elements sont inférieurs à l'element qu'on cherche.
//Soit un entier négatif qui représente l'index de premier element supérieur de l'element qu'on cherche.
int index = Collections.binarySearch(data, prefix);
if(index < 0 && -index <= data.size()) {
//Completion Trouvé
//On récupére le premier element supérieur à l'element cherché. le signe - retourne la valeur absolue de la variable index.
String match = data.get(-index - 1);
//on s'assure que la chaine dans la variable match commence par la chaine contenu dans la variable prefix c-à-d ce qu'a saisi l'utilisateur
if(match.startsWith(prefix)) {
//si oui on met on place l'autocompletion sinon on fait rien :).
SwingUtilities.invokeLater(new AutoCompletion(pos, match));
}
} else ;
//Aucune Completion Trouvé
}
}
/**
* Permet De Valider L'AutoCompletion En Cliquant Sur La Touche Entrer
*/
@Override
public void actionPerformed(ActionEvent e) {
// TODO Stub de la méthode généré automatiquement
setCaretPosition(getSelectionEnd());
}
@Override
public void removeUpdate(DocumentEvent e) {}
@Override
public void changedUpdate(DocumentEvent e) {}
private class AutoCompletion implements Runnable{
private int pos;
private String completion;
public AutoCompletion(int pos, String completion) {
this.pos = pos;
this.completion = completion;
}
@Override
public void run() {
// TODO Stub de la méthode généré automatiquement
//On affecte la chaine trouvé pour l'autocompletion dans le champs de texte
setText(completion);
//on definit à partir d'où va débuter la séléction des caractères ajouté comme completion.
//j'ai précisé qu'il va débuter de la fin vers le dernier caractère sasie par l'utilisateur
setCaretPosition(completion.length());
//j'ai appliqué la séléction jusqu'au dernier caractère sasie par l'utilisateur
moveCaretPosition(pos + 1);
}
}
}