TextField autocompletion is a convenient feature that enhances user experience by providing suggestions or predictions as users type into a text field. JavaFX is a powerful framework for building rich desktop applications, and ControlsFX is a library that extends the capabilities of JavaFX. In this article, we will explore how to implement TextField autocompletion using ControlsFX in a JavaFX application.
Setting Up ControlsFX
Before we begin, make sure you have added the ControlsFX library to your JavaFX project. You can download the ControlsFX library from the official GitHub repository or include it as a dependency using a build tool like Maven or Gradle.
You also need to add the following VM option to your runtime command line:
--add-exports javafx.base/com.sun.javafx.event=ALL-UNNAMED
Basic Autocompletion
ControlsFX provides a convenient API to bind autocompletion to a TextField. Let’s start with the basic usage of autocompletion using a list of possible suggestions.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import org.controlsfx.control.textfield.TextFields;
import java.util.Arrays;
import java.util.List;
public class Main extends Application {
private final BorderPane parent = new BorderPane();
@Override
public void init() throws Exception {
super.init();
// Build the user interface
this.buildUI();
}
private void buildUI() {
// Create the TextField
TextField textField = new TextField();
// Set the TextField width to 300.0 pixels
textField.setMaxWidth(300.0);
// A list of possible suggestions
List<String> possibleSuggestions = Arrays.asList(
"C", "C#", "C++", "F#", "GoLang",
"Dart", "Java", "JavaScript", "Kotlin", "PHP",
"Python", "R", "Swift", "Visual Basic .NET"
);
// Bind autocompletion to the TextField
TextFields.bindAutoCompletion(textField, possibleSuggestions);
// Add the TextField to the center of the BorderPane
this.parent.setCenter(textField);
}
@Override
public void start(Stage stage) throws Exception {
// Setup and display the stage
this.setupStage(stage);
}
private void setupStage(Stage stage) {
// Create a scene with the BorderPane as the root
Scene scene = new Scene(this.parent, 640, 480);
// Set the scene for the stage
stage.setScene(scene);
// Set the stage title
stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");
// Center the stage on the screen
stage.centerOnScreen();
// Display the stage
stage.show();
}
}
In this example, we create a TextField and a list of possible suggestions. The TextFields.bindAutoCompletion method binds autocompletion to the TextField using the list of suggestions. As the user types in the TextField, the autocompletion feature will provide suggestions from the list.
Advanced Autocompletion with Custom Provider
ControlsFX also allows you to provide a custom suggestion provider using a callback. This is useful when you need to retrieve suggestions from a data source or perform custom filtering.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Callback;
import org.controlsfx.control.textfield.AutoCompletionBinding;
import org.controlsfx.control.textfield.TextFields;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class Main extends Application {
private final BorderPane parent = new BorderPane();
@Override
public void init() throws Exception {
super.init();
// Build the user interface
this.buildUI();
}
private void buildUI() {
// Create the TextField
TextField textField = new TextField();
// Set the TextField width to 300.0 pixels
textField.setMaxWidth(300.0);
// A list of possible suggestions
List<String> possibleSuggestions = Arrays.asList(
"C", "C#", "C++", "F#", "GoLang",
"Dart", "Java", "JavaScript", "Kotlin", "PHP",
"Python", "R", "Swift", "Visual Basic .NET"
);
Callback<AutoCompletionBinding.ISuggestionRequest, Collection<String>> suggestionProvider =
request -> possibleSuggestions.stream()
.filter(suggestion -> suggestion.toLowerCase().contains(request.getUserText().toLowerCase()))
.toList();
// Bind autocompletion to the TextField using the custom suggestion provider
TextFields.bindAutoCompletion(textField, suggestionProvider);
// Add the TextField to the center of the BorderPane
this.parent.setCenter(textField);
}
@Override
public void start(Stage stage) throws Exception {
// Setup and display the stage
this.setupStage(stage);
}
private void setupStage(Stage stage) {
// Create a scene with the BorderPane as the root
Scene scene = new Scene(this.parent, 640, 480);
// Set the scene for the stage
stage.setScene(scene);
// Set the stage title
stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");
// Center the stage on the screen
stage.centerOnScreen();
// Display the stage
stage.show();
}
}
In this example, we create a custom suggestion provider using a Callback. The provider filters suggestions based on the user’s input. This allows for more advanced autocompletion behavior, such as retrieving suggestions from a remote server or a database.
Advanced Autocompletion with Custom Converter
A converter is essential when you want to display suggestions in a user-friendly manner while retaining the actual value associated with the suggestion.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
import org.controlsfx.control.textfield.AutoCompletionBinding;
import org.controlsfx.control.textfield.TextFields;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class Main extends Application {
private final BorderPane parent = new BorderPane();
@Override
public void init() throws Exception {
super.init();
// Build the user interface
this.buildUI();
}
private void buildUI() {
// Create the TextField
TextField textField = new TextField();
// Set the TextField width to 300.0 pixels
textField.setMaxWidth(300.0);
// A list of possible suggestions
List<Language> possibleSuggestions = Arrays.asList(
new Language("C"), new Language("C#"), new Language("C++"), new Language("F#"),
new Language("GoLang"), new Language("Dart") , new Language("Java"), new Language("R"),
new Language("JavaScript"), new Language("Kotlin"), new Language("PHP"),
new Language("Python"), new Language("Swift"), new Language("Visual Basic .NET")
);
Callback<AutoCompletionBinding.ISuggestionRequest, Collection<Language>> suggestionProvider =
request -> possibleSuggestions.stream()
.filter(suggestion -> suggestion.name().toLowerCase().contains(request.getUserText().toLowerCase()))
.toList();
StringConverter<Language> converter = new StringConverter<>() {
@Override
public String toString(Language language) {
// Convert suggestion to display text
return language.name();
}
@Override
public Language fromString(String name) {
// Convert selected display text back to suggestion
return possibleSuggestions.stream()
.filter(suggestion -> suggestion.name().equalsIgnoreCase(name))
.findFirst().orElse(null);
}
};
// Bind autocompletion to the TextField using the custom suggestion provider, and converter
TextFields.bindAutoCompletion(textField, suggestionProvider, converter);
// Add the TextField to the center of the BorderPane
this.parent.setCenter(textField);
}
@Override
public void start(Stage stage) throws Exception {
// Setup and display the stage
this.setupStage(stage);
}
private void setupStage(Stage stage) {
// Create a scene with the BorderPane as the root
Scene scene = new Scene(this.parent, 640, 480);
// Set the scene for the stage
stage.setScene(scene);
// Set the stage title
stage.setTitle("TextField Autocompletion in JavaFX using ControlsFX");
// Center the stage on the screen
stage.centerOnScreen();
// Display the stage
stage.show();
}
record Language(String name) {}
}
The toString method of the converter determines how the suggestions are displayed in the autocompletion popup. Customize it to format the suggestions as you desire. The fromString method converts the selected display text back to the actual suggestion value. This is particularly useful if the suggestions and their displayed forms are different.
Conclusion
Adding autocompletion to TextField components in your JavaFX applications can greatly enhance the user experience by making data entry faster and more accurate. The ControlsFX library provides a simple and powerful way to implement autocompletion using various methods, including basic suggestions, custom providers, and string converters. By incorporating autocompletion, you can create more intuitive and user-friendly applications. Remember to check the ControlsFX TextFields documentation for more.
I hope you found this code informative and useful. If you would like to receive more content, please consider subscribing to our newsletter!