Hello I have something that can help you.
You need to tell which Type the box will handle, it can be any object, String, Double, Person.
Only the comparison will be made by the object's toString () method.
public class AutoSuggestComboBox<T> extends StackPane {
private double PREF_HEIGHT = 21.0d;
private TextField textField;
private ComboBox<T> comboBox;
private ObservableList<T> mainList = FXCollections.observableArrayList();
private ObservableList<T> subList = FXCollections.observableArrayList();
private SimpleObjectProperty<T> selectedItem = new SimpleObjectProperty<T>();
private ChangeListener<String> textChangeLister = new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
boolean flag = false;
for (T str : mainList) {
if (str.toString().equalsIgnoreCase(arg2)) {
flag = true;
break;
}
}
if (!flag) {
subList.clear();
for (T str : mainList) {
if (str.toString().toLowerCase().contains(arg2) || str.toString().toUpperCase().contains(arg2)) {
subList.add(str);
}
}
comboBox.show();
}
}
};
public AutoSuggestComboBox() {
super();
setAlignment(Pos.CENTER_LEFT);
getStylesheets().add("br/com/cacti/util/auto-suggest-combo-box.css");
// ComboBox declaration
comboBox = new ComboBox<T>();
comboBox.setItems(subList);
comboBox.setPrefHeight(PREF_HEIGHT);
comboBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<T>() {
@Override
public void changed(ObservableValue<? extends T> paramObservableValue, T paramT1, T paramT2) {
if (paramT2 != null) {
textField.setText(paramT2.toString());
selectedItem.set(paramT2);
}
}
});
comboBox.showingProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> paramObservableValue, Boolean paramT1,
Boolean show) {
if (show) {
for (T str : subList) {
if (str.toString().equalsIgnoreCase(textField.getText())) {
comboBox.getSelectionModel().select(str);
}
}
} else {
subList.clear();
subList.addAll(mainList);
}
}
});
// TextField declaration (for auto suggest)
textField = new TextField();
textField.setFocusTraversable(false);
textField.getStyleClass().add("autoSuggest");
textField.maxHeightProperty().bind(comboBox.heightProperty());
textField.maxWidthProperty().bind(comboBox.widthProperty().subtract(18));
textField.textProperty().addListener(textChangeLister);
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> paramObservableValue, Boolean paramT1,
Boolean focused) {
if (focused) {
comboBox.getStyleClass().add("combo-focused");
} else {
comboBox.getStyleClass().remove("combo-focused");
}
}
});
// Adding the children in the stack pane.
getChildren().addAll(comboBox, textField);
}
/**
* Method to return the ComboBox<T>
*
* @return ComboBox
*/
public ComboBox<T> getComboBox() {
return this.comboBox;
}
/**
* Method to return the selectedItem of the comboBox.
*
* @return SimpleObjectProperty<T>
*/
public SimpleObjectProperty<T> selectedItemProperty() {
return selectedItem;
}
/**
* Method to set the items to the combo box as well as take backup of the
* list. NOTE: To get the actual results of AutoSuggest, Setting of items to
* the combo box should happen through this method only.
*
* @param items
* ObservableList<T>
*/
public void setItemsToCombo(ObservableList<T> items) {
mainList.clear();
subList.clear();
mainList.addAll(items);
subList.addAll(items);
}
public void setPromptText(String value){
textField.setPromptText(value);
}
public void setValue(T valor){
if(valor != null){
selectedItem.set(valor);
textField.setText(valor.toString());
}
}
}
And the css auto-suggest-combo-box.css
.autoSuggest, .autoSuggest:focused{
-fx-padding: 0 5 0 5;
-fx-background-color: -fx-text-box-border, -fx-control-inner-background;
-fx-background-insets: 0, 1 0 1 1;
-fx-background-radius:3 0 0 3;
}
.combo-focused {
-fx-background-color: -fx-focus-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
-fx-background-radius: 6.4, 4, 5, 3;
-fx-background-insets: -1.4, 0, 1, 2;
}