JavaFX TextField 自动建议 [英] JavaFX TextField Auto-suggestions

查看:32
本文介绍了JavaFX TextField 自动建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让这个 TextField 像在 Lucene 中一样具有建议功能.我搜索了所有网络,只找到了 ComboBox.

TextField instNameTxtFld = instNameTxtFld();私人文本字段 instNameTxtFld() {TextField txtFld = new TextField();txtFld.setPrefSize(600, 75);返回 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();} 别的 {字符串饱和 = idNumTxtFld.getText();String dua = nameTxtFld.getText();String tiga = addTxtArea.getText();String empat = instNameTxtFld.getText();int delapan = idType.getSelectionModel().getSelectedIndex();String sembilan = timeStamp.getText();尝试 {KonekDB.createConnection();语句 st = KonekDB.conn.createStatement();字符串 sql = "插入私人访客"+ "(idNumber, 姓名, 地址, 机构, idType, startTime) "+价值观"+ "('" + 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 异常(下一个)");ex.printStackTrace();}Frame3Private frame3 = new Frame3Private(english);this.getScene().setRoot(frame3);}}

请帮我编写最简单的代码来执行 TextField 建议/自动完成.

解决方案

这是我基于

希望有帮助.

I want to make this TextField have suggestions feature just like in Lucene. I've searched all the web and I just find it for ComboBox.

TextField instNameTxtFld = instNameTxtFld();

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

The reason that I can't use the method for ComboBox is because I can't input the value to database below if I use 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);
    }

}

Please help me to make the most simple code for doing TextField suggestions/ auto-complete.

解决方案

Here is my solution based on 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; }
}

You must extends from "TextField" instead of "TextFieldWithLengthLimit" and delete constructor with "Length limit".

I use static methods to work with Styles. It's used here to "highlight" entered text inside suggestion results. Here is the code of methos from this class:

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

You may add this "AutocompletionlTextField" in FXML (dont forget about "imports") or inside constructor. To set "suggestions" list on use "entries" getter:

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

It seems like that in my application:

Hope it helps.

这篇关于JavaFX TextField 自动建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆