2016-06-14 63 views
-1

我想執行jtextfield的自動完成,爲此目的,我谷歌它,並發現一些很好的例子和代碼片段,但我的情況是從所有這些不同,通常每個示例自動完成字段,例如說,如果我按小號它會自動完成#1或者如果我按它將完成谷歌等,意味着其只需要對自動完成第一個字符。從特定長度自動完成jtextfield

但我的問題是這樣的,我想執行自動完成時,前4個字符將輸入或輸入的說,如果我輸入STAC比它應該是自動完成它計算器,不與第一字符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("stackoverflow"); 
     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); 
    } 
} 
+0

(1)'我google一下,發現了一些好的examples' - 所以後來修改的例子,以滿足您的要求。您可以輕鬆檢查當前在文本字段中輸入的字符數量。 – camickr

+0

@(1-)我在上面發佈我的代碼,請你幫助我。 – ahad

+0

我確實給過幫助。您檢查文本字段中文本的長度。如果長度是你想要的,你會進行處理,否則你只需退出該方法。 – camickr

回答

0

根據你的問題,你要執行自動完成時,前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); 
    }  
} 

}