Jfoenix: Autocomplete on JFXComboBox

Created on 6 Jan 2017  路  10Comments  路  Source: sshahine/JFoenix

Is there any way to turn on autocomplete on JFXComboBox? I know that there is option to call:

TextFields.bindAutoCompletion(comboBox.getJFXEditor(), "option1", "option2");

but appearance of autocomplete from ControlsFx:
image
and ComboBox from JFoenix
image
are completly diffrent.

It would be great to have this little option integrated too 馃槂

Docs Needed Enhancement

Most helpful comment

After a glance at the JFXChipView (specifically JFXChipViewSkin and JFXAutoCompletePopup), the JFXAutoCompletePopup can be used on a JFXComboBox in this way:

JFXComboBox<String> comboBox = new JFXComboBox<>();
comboBox.getItems().addAll("HELLO", "TROLL", "WFEWEF", "WEF");

JFXAutoCompletePopup<String> autoCompletePopup = new JFXAutoCompletePopup<>();
autoCompletePopup.getSuggestions().addAll(comboBox.getItems());

//SelectionHandler sets the value of the comboBox
autoCompletePopup.setSelectionHandler(event -> {
    comboBox.setValue(event.getObject());
});

TextField editor = comboBox.getEditor();
editor.textProperty().addListener(observable -> {
    //The filter method uses the Predicate to filter the Suggestions defined above
    //I choose to use the contains method while ignoring cases
    autoCompletePopup.filter(item -> item.toLowerCase().contains(editor.getText().toLowerCase()));
    //Hide the autocomplete popup if the filtered suggestions is empty or when the box's original popup is open
    if (autoCompletePopup.getFilteredSuggestions().isEmpty() || customerComboBox.showingProperty().get()) {
        autoCompletePopup.hide();
    } 
    else {
        autoCompletePopup.show(editor);
    }
});

I did not test it with JFXTextField but I assume this is even easier as you do not have to worry about the ComboBox popup, or for instance synchronizing the ComboBox items with the Suggestions (which I did not do in this simple example). Please note that the autocomplete popup's default skin is different than the ComboBox's popup skin.

All 10 comments

Hello,
Currently there is no autocomplete feature in JFoenix. You can use the ControlFX autocomplete and customize both popup lists using css so they look the same.

Regards,

I use this, hope it solve

public class AutoCompleteComboBoxListener<T> implements EventHandler<KeyEvent> {
    private JFXComboBox<T> comboBox;
    private ObservableList<T> data;
    private boolean moveCaretToPos = false;
    private int caretPos;

    AutoCompleteComboBoxListener(final JFXComboBox<T> comboBox) {
        this.comboBox = comboBox;
        data = comboBox.getItems();

        this.comboBox.setEditable(true);
        this.comboBox.setOnKeyPressed(t -> comboBox.hide());
        this.comboBox.setOnKeyReleased(AutoCompleteComboBoxListener.this);
    }

    @Override
    public void handle(KeyEvent event) {

        if(event.getCode() == KeyCode.UP) {
            caretPos = -1;
            moveCaret(comboBox.getEditor().getText().length());
            return;
        } else if(event.getCode() == KeyCode.DOWN) {
            if(!comboBox.isShowing()) {
                comboBox.show();
            }
            caretPos = -1;
            moveCaret(comboBox.getEditor().getText().length());
            return;
        } else if(event.getCode() == KeyCode.BACK_SPACE) {
            moveCaretToPos = true;
            caretPos = comboBox.getEditor().getCaretPosition();
        } else if(event.getCode() == KeyCode.DELETE) {
            moveCaretToPos = true;
            caretPos = comboBox.getEditor().getCaretPosition();
        }

        if(event.getCharacter().matches("[a-z]"))
            comboBox.setValue((T) String.valueOf(comboBox.getValue()).toUpperCase());

        if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
                || event.isControlDown() || event.getCode() == KeyCode.HOME
                || event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
            return;
        }

        ObservableList<T> list = FXCollections.observableArrayList();
        for (T aData : data) {
            if (String.valueOf(aData).toLowerCase().startsWith(
                    AutoCompleteComboBoxListener.this.comboBox
                            .getEditor().getText().toLowerCase())) {
                list.add(aData);
            }
        }
        String t = comboBox.getEditor().getText();

        comboBox.setItems(list);
        comboBox.getEditor().setText(t);
        if(!moveCaretToPos) {
            caretPos = -1;
        }
        moveCaret(t.length());
        if(!list.isEmpty()) {
            comboBox.show();
        }
    }

    private void moveCaret(int textLength) {
        if(caretPos == -1) {
            comboBox.getEditor().positionCaret(textLength);
        } else {
            comboBox.getEditor().positionCaret(caretPos);
        }
        moveCaretToPos = false;
    }
}

We added a new control to JFoenix JFXAutoCompletePopup that can be used along with JFXTextField ( or any other editable controls). For example, you can check the new chip view demo.

Regards,

Any small example of how to integrate the JFXAutoCompletePopup with a JFXTextfield or a JFXCombobox?

After a glance at the JFXChipView (specifically JFXChipViewSkin and JFXAutoCompletePopup), the JFXAutoCompletePopup can be used on a JFXComboBox in this way:

JFXComboBox<String> comboBox = new JFXComboBox<>();
comboBox.getItems().addAll("HELLO", "TROLL", "WFEWEF", "WEF");

JFXAutoCompletePopup<String> autoCompletePopup = new JFXAutoCompletePopup<>();
autoCompletePopup.getSuggestions().addAll(comboBox.getItems());

//SelectionHandler sets the value of the comboBox
autoCompletePopup.setSelectionHandler(event -> {
    comboBox.setValue(event.getObject());
});

TextField editor = comboBox.getEditor();
editor.textProperty().addListener(observable -> {
    //The filter method uses the Predicate to filter the Suggestions defined above
    //I choose to use the contains method while ignoring cases
    autoCompletePopup.filter(item -> item.toLowerCase().contains(editor.getText().toLowerCase()));
    //Hide the autocomplete popup if the filtered suggestions is empty or when the box's original popup is open
    if (autoCompletePopup.getFilteredSuggestions().isEmpty() || customerComboBox.showingProperty().get()) {
        autoCompletePopup.hide();
    } 
    else {
        autoCompletePopup.show(editor);
    }
});

I did not test it with JFXTextField but I assume this is even easier as you do not have to worry about the ComboBox popup, or for instance synchronizing the ComboBox items with the Suggestions (which I did not do in this simple example). Please note that the autocomplete popup's default skin is different than the ComboBox's popup skin.

I've used the following code it works but when you run project it will pop-up even not focused and typed. What is the reason for that?

@elgolondrino
The reason for that the JFXAutoCompletePopup in Jetlagh's example pops up when running a project is that he added a Listener to the TextField's textProperty(): editor.textProperty().addListener(...);
So when you run your project, the textProperty() gets changed when a default item is selected in the ComboBox: from an empty String (? I assume) to your value.

My workaround:
I've added an EventHandler to the editor to handle any KeyEvents:
editor.addEventHandler(KeyEvent.ANY, event -> {...} _insert Jetlagh's code for the listener_
And if you want the arrow keys to still work, instead of just using Jetlagh's code for the listener, you can add an if-statement in your EventHandler: if (!event.getCode().isNavigationKey()) {...}

@Jetlagh
Is comboBox.setValue(event.getObject()); basically the same as comboBox.getSelectionModel().select(event.getObject()); in your example? If yes, is this generally valid or does it apply only to this example?

What does the following extract from the JavaDoc of ComboBox mean exactly?
"The value property is not constrained to items contained within the items list - it can be anything as long as it is a valid value of type T."

How do I limit the auto completion results?

Is there a way to use CSS to style the drop down list background color of the Combo Box? I am using ComboBox (not JFXComboBox) & trying JFoenix Autocompletion, but the CSS styling not working.

I tried with below code as shown in https://github.com/jfoenixadmin/JFoenix/issues/644#issuecomment-372615626
.autocomplete-popup .autocomplete-list {
-fx-background-color: yellow;
}

CC: @Ordinateur-Hack @jfoenixadmin can you help ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alittwin picture alittwin  路  4Comments

ivanskodje picture ivanskodje  路  4Comments

imgx64 picture imgx64  路  5Comments

caoyanfeng picture caoyanfeng  路  3Comments

TurekBot picture TurekBot  路  5Comments