Galera, como eu precisei, acredito que outros irão precisar, então estou compartilhando a classe que faz o AutoComplete num JFXComboBox utilizando JavaFX.
1-Adicione uma nova classe no pacote util de seu projeto com nome “utilAutoCompleteComboBox”.
2-Cole o código abaixo:
package informe o caminho do pacote aqui;
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;
public class utilAutoCompleteComboBox<T> implements EventHandler<KeyEvent> {
private ComboBox comboBox;
private StringBuilder sb;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
public utilAutoCompleteComboBox(final ComboBox comboBox) {
this.comboBox = comboBox;
sb = new StringBuilder();
data = comboBox.getItems();
this.comboBox.setEditable(true);
this.comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
comboBox.hide();
}
});
this.comboBox.setOnKeyReleased(utilAutoCompleteComboBox.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.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
ObservableList list = FXCollections.observableArrayList();
for (int i = 0; i < data.size(); i++) {
if (data.get(i).toString().toLowerCase().startsWith(utilAutoCompleteComboBox.this.comboBox
.getEditor().getText().toLowerCase())) {
list.add(data.get(i));
}
}
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;
}
}
3-Lá no controller da tela que você tem o JFXComboBox você inclui este método abaixo:
//Método que popula o JFXComboBox usuário da tela de login e implementa o AutoComplete
private void carregaUsuario() {
try {
//Lista que receberá os dados do BD (Usuários)
//Para alimentar o JFXComboBox usuário
List<String> lista = new ArrayList<>();
Connection conn = dbConexao.getConnection();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT username FROM usuarios ORDER BY username ASC");
if (rs.next()) {//Caso puxar dados do BD
while (rs.next()) {//Popula o comboBox
//Passa por todos os registros e adiciona na lista
lista.add(rs.getString("username"));
//Adiciona a lista ao JFXComboBox
SEU_COMBOBOX_AQUI.setItems(FXCollections.observableArrayList(lista));
//Implementa o AutoComplete utilizando a classe utilAutoCompleteComboBox
new utilAutoCompleteComboBox<>(SEU_COMBOBOX_AQUI);
}
} else {//Caso não puxar dados do BD emite a msg de erro
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Alerta!");
alert.setHeaderText("O servidor está offline");
alert.setContentText("Tente novamente ou entre em contato com o suporte técnico");
alert.initStyle(StageStyle.UNDECORATED);
alert.showAndWait();//Emite o alerta de erro servidor
SEU_COMBOBOX_AQUI.requestFocus();
}
dbConexao.close((com.mysql.jdbc.Connection) conn, st, rs);
} catch (Exception ex) {
ex.printStackTrace();
System.err.println("ERR" + ex);
}
}
4-No mesmo controller, dentro do método default “initialize” você vai chamar o método acima “carregaUsuario();”, assim que a tela for iniciada vai popular o JFXComboBox e implementar o AutoComplete:
@Override
public void initialize(URL url, ResourceBundle rb) {
//Chamada dos métodos
carregaUsuario();//Popula o JFXComboBox usuário com AutoComplete
}
Fim! 