2016-04-26 27 views
2

Ich möchte, dass dieses TextField wie in Lucene Vorschläge enthält. Ich habe das ganze Web durchsucht und finde es nur für ComboBox.JavaFX TextField Automatische Vorschläge

TextField instNameTxtFld = instNameTxtFld(); 

private TextField instNameTxtFld() { 
    TextField txtFld = new TextField(); 
    txtFld.setPrefSize(600, 75); 
    return txtFld; 
} 

Der Grund, dass ich nicht die Methode für die ComboBox verwenden kann, ist, weil ich kann nicht eingegeben um den Wert Datenbank unten, wenn ich ComboBox verwenden.

private void goNext() { 

    if (nameTxtFld.getText() == null || nameTxtFld.getText().trim().isEmpty() 
      || instNameTxtFld.getText()== null || instNameTxtFld.getText().trim().isEmpty() 
      || addTxtArea.getText() == null || addTxtArea.getText().trim().isEmpty()) { 
     alertDialog.showAndWait(); 
    } else { 
     String satu = idNumTxtFld.getText(); 
     String dua = nameTxtFld.getText(); 
     String tiga = addTxtArea.getText(); 
     String empat = instNameTxtFld.getText(); 
     int delapan = idType.getSelectionModel().getSelectedIndex(); 
     String sembilan = timeStamp.getText(); 
     try { 
      KonekDB.createConnection(); 
      Statement st = KonekDB.conn.createStatement(); 
      String sql = "INSERT INTO privateguest" 
        + "(idNumber, name, address, institution, idType, startTime) " 
        + "VALUES " 
        + "('" + satu + "','" + dua + "','" + tiga + "','" + empat + "','" + delapan + "','" + sembilan + "')"; 

      System.out.println(sql); 
      st.executeUpdate(sql); 

     } catch (SQLException ex) { 

      System.out.println(satu + " " + dua + " " + tiga + " " + empat + " " + delapan + " " + sembilan); 
      System.out.println("SQL Exception (next)"); 
      ex.printStackTrace(); 
     } 
     Frame3Private frame3 = new Frame3Private(english); 
     this.getScene().setRoot(frame3); 
    } 

} 

Bitte helfen Sie mir, den einfachsten Code für TextField Vorschläge/Auto-Vervollständigen zu machen.

+0

Haben Sie von [ControlsFX] (http://fxexperience.com/controlsfx/features/) mit 'AutoComplete' in Betracht ziehen? – Itai

Antwort

7

Hier ist meine Lösung basierend auf This.

public class AutocompletionlTextField extends TextFieldWithLengthLimit { 
    //Local variables 
    //entries to autocomplete 
    private final SortedSet<String> entries;  
    //popup GUI 
    private ContextMenu entriesPopup; 


    public AutocompletionlTextField() { 
     super(); 
     this.entries = new TreeSet<>(); 
     this.entriesPopup = new ContextMenu(); 

     setListner(); 
    } 


    /** 
    * wrapper for default constructor with setting of "TextFieldWithLengthLimit" LengthLimit 
    * 
    * @param lengthLimit 
    */ 
    public AutocompletionlTextField(int lengthLimit) {   
     this(); 
     super.setLengthLimit(lengthLimit);     
    } 


    /** 
    * "Suggestion" specific listners 
    */ 
    private void setListner() {  
     //Add "suggestions" by changing text 
     textProperty().addListener((observable, oldValue, newValue) -> { 
      String enteredText = getText(); 
      //always hide suggestion if nothing has been entered (only "spacebars" are dissalowed in TextFieldWithLengthLimit) 
      if (enteredText == null || enteredText.isEmpty()) { 
       entriesPopup.hide(); 
      } else { 
       //filter all possible suggestions depends on "Text", case insensitive 
       List<String> filteredEntries = entries.stream() 
         .filter(e -> e.toLowerCase().contains(enteredText.toLowerCase())) 
         .collect(Collectors.toList()); 
       //some suggestions are found 
       if (!filteredEntries.isEmpty()) { 
        //build popup - list of "CustomMenuItem" 
        populatePopup(filteredEntries, enteredText); 
        if (!entriesPopup.isShowing()) { //optional 
         entriesPopup.show(AutocompletionlTextField.this, Side.BOTTOM, 0, 0); //position of popup 
        } 
       //no suggestions -> hide 
       } else { 
        entriesPopup.hide(); 
       } 
      } 
     }); 

     //Hide always by focus-in (optional) and out 
     focusedProperty().addListener((observableValue, oldValue, newValue) -> { 
      entriesPopup.hide(); 
     }); 
    }    


    /** 
    * Populate the entry set with the given search results. Display is limited to 10 entries, for performance. 
    * 
    * @param searchResult The set of matching strings. 
    */ 
    private void populatePopup(List<String> searchResult, String searchReauest) { 
     //List of "suggestions" 
     List<CustomMenuItem> menuItems = new LinkedList<>(); 
     //List size - 10 or founded suggestions count 
     int maxEntries = 10; 
     int count = Math.min(searchResult.size(), maxEntries); 
     //Build list as set of labels 
     for (int i = 0; i < count; i++) { 
      final String result = searchResult.get(i); 
      //label with graphic (text flow) to highlight founded subtext in suggestions 
      Label entryLabel = new Label(); 
      entryLabel.setGraphic(Styles.buildTextFlow(result, searchReauest)); 
      entryLabel.setPrefHeight(10); //don't sure why it's changed with "graphic" 
      CustomMenuItem item = new CustomMenuItem(entryLabel, true); 
      menuItems.add(item); 

      //if any suggestion is select set it into text and close popup 
      item.setOnAction(actionEvent -> { 
       setText(result); 
       positionCaret(result.length()); 
       entriesPopup.hide(); 
      }); 
     } 

     //"Refresh" context menu 
     entriesPopup.getItems().clear(); 
     entriesPopup.getItems().addAll(menuItems); 
    } 


    /** 
    * Get the existing set of autocomplete entries. 
    * 
    * @return The existing autocomplete entries. 
    */ 
    public SortedSet<String> getEntries() { return entries; } 
} 

Sie müssen sich von „TextField-“ statt „TextFieldWithLengthLimit“ und löschen Konstruktor mit „Length Limit“.

Ich verwende statische Methoden, um mit Stilen zu arbeiten. Es wird hier verwendet, um den eingegebenen Text in den Vorschlagsergebnissen zu "markieren". Hier ist der Code von methos aus dieser Klasse:

/** 
* Build TextFlow with selected text. Return "case" dependent. 
* 
* @param text - string with text 
* @param filter - string to select in text 
* @return - TextFlow 
*/ 
public static TextFlow buildTextFlow(String text, String filter) {   
    int filterIndex = text.toLowerCase().indexOf(filter.toLowerCase()); 
    Text textBefore = new Text(text.substring(0, filterIndex)); 
    Text textAfter = new Text(text.substring(filterIndex + filter.length())); 
    Text textFilter = new Text(text.substring(filterIndex, filterIndex + filter.length())); //instead of "filter" to keep all "case sensitive" 
    textFilter.setFill(Color.ORANGE); 
    textFilter.setFont(Font.font("Helvetica", FontWeight.BOLD, 12)); 
    return new TextFlow(textBefore, textFilter, textAfter); 
}  

Sie können dieses „AutocompletionlTextField“ add in FXML (nicht vergessen „Importe“) oder im Konstruktor. Um "Vorschläge" -Liste auf der Verwendung "Einträge" Getter gesetzt:

AutocompletionlTextField field = new AutocompletionlTextField(); 
field.getEntries().addAll(YOUR_ARRAY_OF_STRINGS); 

Es scheint so, dass in meiner Anwendung: enter image description here

Hoffe, es hilft.

+0

Wo befindet sich TextFieldWithLengthLimit? – firephil

+0

Es war meine eigene Komponente - Sie beachten TextField stattdessen. Wie in meinem Kommentar wrotten: "Sie müssen von" TextField "statt" TextFieldWithLengthLimit "erweitern und Konstruktor mit" Length limit "löschen. –

+0

ok danke, versuchen Sie, beim nächsten Mal den Arbeitscode zu posten und den TextFieldWithLengthLimit-Code auch zu posten ... – firephil

6

Sie können ControlsFX verwenden ->maven

Lösung:

TextFields.bindAutoCompletion(textfield,"text to suggest", "another text to suggest"); 
+1

Schnelle Lösung. Aber es ist wirklich langsam zu Popup, ich kann das ganze Wort eingeben, bevor das Popup auftaucht. –

Verwandte Themen