1

I'm writing a program which involves having a user type in a combo box and the list of items should change to reflect the text in the box (similar to autocomplete when you type into Google)

However, my combo box will not update until I press Enter. It doesn't seem to update when regular keys are typed. I have tried adding all kinds of listeners to the combo box but none of them fix the problem.

Here is the code snippet that has been the most successful. It is called from the fxml code: onKeyReleased="#keyReleased". It works properly, but still only executes when Enter is pressed.

public void keyReleased() throws SQLException, ClassNotFoundException
{
    String coname = custconame_combo.getValue();

    scriptHandler = new ScriptHandler();

    custconame_combo.getItems().clear();
    int i = 0;
    for (String s : scriptHandler.searchCustomer(coname))
    {
        System.out.println(s);
        custconame_combo.getItems().add(s);

        custconame_combo.show();

        i += 1;
    }
}

I have searched high and low and still can't seem to solve this issue.

kleopatra
  • 49,346
  • 26
  • 88
  • 189
  • `ComboBox` has an `editor` property which contains a `TextField`. Have you tried listing to the `text` property of that `TextField` for changes? – Slaw Aug 24 '18 at 03:28
  • As @Slaw mentioned, try adding your listener to the editor's `TextField` instead: `comboBox.getEditor().textProperty().addListener()` – Zephyr Aug 24 '18 at 03:51
  • 1
    I do recommend caution with this design, however, as adding a new entry to the `ComboBox` every time a key is entered may not be the expected user experience. Wouldn't it be best to add the new item only after the user has finished typing the entire entry? – Zephyr Aug 24 '18 at 03:52
  • 2
    Please provide a [mcve] that demonstrates the problem. – kleopatra Aug 24 '18 at 08:30
  • @Zephyr I have tried adding a listener to the text property, using `custphone_combo.getEditor().textProperty().addListener(...)` but when I use that, nothing is executed. Not even after pressing enter. Also, I am adding a new entry after every key press because the person I am working with wants an auto-complete like function to cut down on typos. – Lauren Montemayor Aug 25 '18 at 16:00
  • @LaurenMontemayor - There was a similar question asked just before yours: https://stackoverflow.com/questions/51993138/javafx-editable-combobox-with-history-function/51993469#51993469 Does that answer help in your situation? – Zephyr Aug 25 '18 at 16:03
  • Also, check out this question for an auto-complete combobox, already answered on SO: https://stackoverflow.com/questions/19924852/autocomplete-combobox-in-javafx – Zephyr Aug 25 '18 at 16:04
  • @Zephyr Thanks for the links! I'll try those solutions asap when I get back to work, it would be great to finally get this working properly. – Lauren Montemayor Aug 25 '18 at 21:52

2 Answers2

0

Since I've solved my problem, I'll share what I found.

Third party libraries provided the easiest solution. I went with the autocompletion class from JFoenix. It has exactly the functionality I was looking for and didn't feel like I was trying to reinvent the wheel.

This answer was very helpful in my search: JavaFX TextField Auto-suggestions

0

Just had a similiar porblem. The onKeyReleased method doesn't respond as needed. Use the EventHandler. Here is my code (just tested and works well):

currencySymbolComboBox.setOnKeyPressed(event -> {
        if(currencySymbolComboBox.isShowing()) {
            if(event.getCode().isLetterKey()) {
                currencyComboBoxKeysTyped += event.getCode().getName();

                Optional<String> os = currecnySymbolsObservableList.stream()
                        .filter(symbol -> symbol.startsWith(currencyComboBoxKeysTyped))
                        .findFirst();

                if (os.isPresent()) {
                    int ind = currecnySymbolsObservableList.indexOf(os.get());
                    ListView<String> lv = ((ComboBoxListViewSkin) currencySymbolComboBox.getSkin()).getListView();
                    lv.getFocusModel().focus(ind);
                    lv.scrollTo(ind);
                    currencySymbolComboBox.getSelectionModel().select(ind);
                } else {
                    currencyComboBoxKeysTyped = currencyComboBoxKeysTyped
                            .substring(0, currencyComboBoxKeysTyped.length() - 1);
                }
            }
            else if(event.getCode() == KeyCode.BACK_SPACE) {
                if(currencyComboBoxKeysTyped.length() > 0) {
                    currencyComboBoxKeysTyped = currencyComboBoxKeysTyped
                            .substring(0, currencyComboBoxKeysTyped.length() - 1);
                }
            }
        }
    });

    currencySymbolComboBox.showingProperty().addListener((observable, oldValue, newValue) -> {
        if(!currencySymbolComboBox.isShowing()) {
            currencyComboBoxKeysTyped = "";
        }
    });
Paweł
  • 1