Después de tanto trabajar ya encontramos el resultado de esta dificultad que tantos lectores de nuestro espacio presentan. Si deseas aportar algo más no dejes de dejar tu información.
Solución:
Primero, tendrás que crear esta clase en tu proyecto:
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 FxUtilTest
public interface AutoCompleteComparator
boolean matches(String typedText, T objectToCompare);
public static void autoCompleteComboBoxPlus(ComboBox comboBox, AutoCompleteComparator comparatorMethod)
ObservableList data = comboBox.getItems();
comboBox.setEditable(true);
comboBox.getEditor().focusedProperty().addListener(observable ->
if (comboBox.getSelectionModel().getSelectedIndex() < 0)
comboBox.getEditor().setText(null);
);
comboBox.addEventHandler(KeyEvent.KEY_PRESSED, t -> comboBox.hide());
comboBox.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler()
private boolean moveCaretToPos = false;
private int caretPos;
@Override
public void handle(KeyEvent event) event.getCode().equals(KeyCode.CONTROL)
private void moveCaret(int textLength)
if (caretPos == -1)
comboBox.getEditor().positionCaret(textLength);
else
comboBox.getEditor().positionCaret(caretPos);
moveCaretToPos = false;
);
public static T getComboBoxValue(ComboBox comboBox)
if (comboBox.getSelectionModel().getSelectedIndex() < 0)
return null;
else
return comboBox.getItems().get(comboBox.getSelectionModel().getSelectedIndex());
Para hacer tu ComboBox
autocompletar, utilícelo así:
FxUtilTest.autoCompleteComboBoxPlus(myComboBox, (typedText, itemToCompare) -> itemToCompare.getName().toLowerCase().contains(typedText.toLowerCase()) || itemToCompare.getAge().toString().equals(typedText));
Luego, agregue un StringConverter
como el siguiente ejemplo (porque el ComboBox
el valor devolverá un String
y tiene que convertirse en su objeto):
myComboBox.setConverter(new StringConverter<>()
@Override
public String toString(YourObject object)
return object != null ? object.getName() : "";
@Override
public YourObject fromString(String string)
return myComboBox.getItems().stream().filter(object ->
object.getName().equals(string)).findFirst().orElse(null);
);
También asegúrese de usar este método cuando necesite obtener el valor seleccionado del cuadro combinado, de lo contrario, puede enfrentar algunas excepciones como "excepción de conversión de clase":
FxUtilTest.getComboBoxValue(myComboBox);
PD: Hubo algunos problemas con este método en las versiones entre JRE 8.51 y 8.65 que causaron algunos comportamientos extraños, ahora los problemas parecen no ocurrir más. Si tiene algún problema, puede ver las ediciones realizadas en esta respuesta y obtener la versión anterior que solucionó el problema en ese momento. Este método debe funcionar bien, si tiene algún problema, hágamelo saber.
Encontré una solución que me funciona:
public class AutoCompleteComboBoxListener implements EventHandler
private ComboBox comboBox;
private StringBuilder sb;
private ObservableList data;
private boolean moveCaretToPos = false;
private int caretPos;
public AutoCompleteComboBoxListener(final ComboBox comboBox)
this.comboBox = comboBox;
sb = new StringBuilder();
data = comboBox.getItems();
this.comboBox.setEditable(true);
this.comboBox.setOnKeyPressed(new EventHandler()
@Override
public void handle(KeyEvent t)
comboBox.hide();
);
this.comboBox.setOnKeyReleased(AutoCompleteComboBoxListener.this);
@Override
public void handle(KeyEvent event)
private void moveCaret(int textLength)
if(caretPos == -1)
comboBox.getEditor().positionCaret(textLength);
else
comboBox.getEditor().positionCaret(caretPos);
moveCaretToPos = false;
Puedes llamarlo con
new AutoCompleteComboBoxListener<>(comboBox);
Se basa en esto y lo personalicé para satisfacer mis necesidades.
Siéntete libre de usarlo y si alguien puede mejorarlo, dímelo.
Con la biblioteca ControlsFX puedes hacerlo con dos líneas de código:
comboBox.setEditable(true);
TextFields.bindAutoCompletion(comboBox.getEditor(), comboBox.getItems());
Si guardas algún reparo o disposición de acrecentar nuestro post puedes escribir una observación y con gusto lo analizaremos.