Thanks to @SedJ601 for the inspiration that led me to take a new approach which solved all my problems! In order to use results from a database, but also change the values that are bound to the textfield based on what is input. You must bind the textfield using a suggestion provider that is bound to a list. Then based on the On Key Typed, whenever the user input is at the length needed, you query the database and populate the query results in the list. This way, you only bind the textfield once, but constantly manipulate that list itself. I previously attempted to do this without using the suggestion provider using the method:
TextFields.bindAutoCompletion(TextField tf, Collection<E> c);
USING THE ABOVE METHOD will not work with manipulating the list. You must use the suggestion provider method below in your initialize() method:
List<String> autoCompleteModels = new ArrayList<>();
@FXML private void initialize(){
TextFields
.bindAutoCompletion(modelQuickSearchTextField, input -> {
if (input.getUserText().length() < 2) {
return Collections.emptyList();
}
return autoCompleteModels.stream().filter(s -> s.toLowerCase().contains(input.getUserText().toLowerCase())).collect(Collectors.toList());
})
.setOnAutoCompleted( e -> {
String model = e.getCompletion().split("\s\\|\s")[0];
openExistingInventory(SimpleCypher.getModelData(model));
modelQuickSearchTextField.clear();
});
}
And then use this method "On Key Typed" (I have it as a seperate method since I'm using JavaFX FXML Scenebuilder, but you can also do textField.onKeyTyped())
//TextField On Key Typed
@FXML TextField modelQuickSearchTextField;
@FXML private void modelAutoComplete() {
String input = modelQuickSearchTextField.getText().toUpperCase();
if (input.length() == 2) {
Task<List<String>> queryTask = new Task<>() {
@Override
protected List<String> call() throws Exception {
List<String> resultModels = new ArrayList<>();
try (Session session = DatabaseConnection.getSession()) {
Result result = session.run("""
MATCH (mo:InventoryModel)
WHERE mo.id CONTAINS $textFieldInput
CALL{
WITH mo
OPTIONAL MATCH (mo)-[:EXISTS_AS]->(:InventoryItem)-[hcs:HAS_CURRENT_STATUS]->(:Status{id:'AVAILABLE'})
RETURN sum(hcs.qty) AS available
}
RETURN mo.id + ' | ' + toString(available)
""",
Values.parameters("textFieldInput", input));
while (result.hasNext()) {
Record record = result.next();
resultModels.add(record.get(0).asString());
}
}
return resultModels;
}
};
queryTask.setOnSucceeded(event -> autoCompleteModels = queryTask.getValue());
// Start the task asynchronously
Thread queryThread = new Thread(queryTask);
queryThread.setDaemon(true); // Set as daemon thread to allow application exit
queryThread.start();
}
}