2016-04-26 2 views
2

Я хочу, чтобы у этого TextField есть предложения, как в Lucene. Я искал всю сеть, и я просто нашел ее для ComboBox.JavaFX TextField Auto-предложения

TextField instNameTxtFld = instNameTxtFld(); 

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

Причина, по которой я не могу использовать метод ComboBox это потому, что не может ввести значение в базе данных ниже, если я использую ComboBox.

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); 
    } 

} 

Пожалуйста, помогите мне сделать самый простой код для выполнения предложений TextField/автозаполнения.

+0

ли вы рассмотреть вопрос об использовании 'AutoComplete' из [ControlsFX] (http://fxexperience.com/controlsfx/features/)? – Itai

ответ

7

Это мое решение основано на 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; } 
} 

Вы должны простирается от «TextField» вместо «TextFieldWithLengthLimit» и удалить конструктор с «предел длины».

Я использую статические методы для работы со стилями. Он используется здесь, чтобы «выделить» введенный текст в результатах предложения. Вот код Митосе из этого класса:

/** 
* 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); 
}  

Вы можете добавить это «AutocompletionlTextField» в FXML (не забудьте про «импорт») или внутри конструктора. Для того, чтобы установить список «предложений» на использовании «записи» добытчик:

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

Похоже, что в моем приложении: enter image description here

Надеется, что это помогает.

+0

Где находится TextFieldWithLengthLimit? – firephil

+0

Это был мой собственный собеседник - вы прислушались к использованию TextField. Как и в моем комментарии wrotten: «Вы должны перейти от« TextField »вместо« TextFieldWithLengthLimit »и удалить конструктор с« Ограничением длины ». –

+0

ОК спасибо, попробуйте отправить рабочий код в следующий раз и опубликуйте TextFieldWithLengthLimit код также ... – firephil

6

Вы можете использовать ControlsFX ->maven

Решение:

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

Быстрое решение. Но это очень медленно всплывающее окно, я могу напечатать все слово до появления всплывающего окна. –

Смежные вопросы