Skip to content

Instantly share code, notes, and snippets.

@acmi
Created May 18, 2016 16:51
Show Gist options
  • Save acmi/cd40945621d0dc10fd16e72868ec4abc to your computer and use it in GitHub Desktop.
Save acmi/cd40945621d0dc10fd16e72868ec4abc to your computer and use it in GitHub Desktop.
Auto comple ComboBox for JavaFX.
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.ComboBox;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
public class AutoCompleteComboBox {
public enum AutoCompleteMode {
STARTS_WITH((s1, s2) -> s1.toLowerCase().startsWith(s2.toLowerCase())),
CONTAINING((s1, s2) -> s1.toLowerCase().contains(s2.toLowerCase()));
private BiPredicate<String, String> filter;
AutoCompleteMode(BiPredicate<String, String> filter) {
this.filter = filter;
}
}
public static <T> void autoCompleteComboBox(ComboBox<T> comboBox, AutoCompleteMode mode) {
ObservableList<T> data = comboBox.getItems();
comboBox.setEditable(true);
comboBox.setOnKeyPressed(event -> comboBox.hide());
comboBox.setOnKeyReleased(new EventHandler<KeyEvent>() {
private boolean moveCaretToPos = false;
private int caretPos;
@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.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT || event.getCode().equals(KeyCode.SHIFT) || event.getCode().equals(KeyCode.CONTROL)
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
ObservableList<T> list = FXCollections.observableList(
data.stream()
.filter(aData -> mode.filter.test(aData.toString(), comboBox.getEditor().getText()))
.collect(Collectors.toList()));
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;
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment